Browse Source

make sure we don't nuke any lists

master
Silberengel 1 month ago
parent
commit
3c1f6b6357
  1. 77
      src/lib/services/user-actions.ts

77
src/lib/services/user-actions.ts

@ -239,29 +239,37 @@ async function publishPinList(eventIds: string[]): Promise<{ success: string[];
return { success: [], failed: [] }; // No changes, cancel operation return { success: [], failed: [] }; // No changes, cancel operation
} }
// Build final tags: preserve all a-tags, add/update e-tags // Build final tags: preserve all a-tags, preserve existing e-tags, add new e-tags
const tags: string[][] = []; const tags: string[][] = [];
const seenEventIds = new Set<string>();
// First, add all existing a-tags (they take precedence) // First, add all existing a-tags (they take precedence)
for (const aTag of existingATags) { for (const aTag of existingATags) {
tags.push(aTag); tags.push(aTag);
} }
// Then, add e-tags for all event IDs in the final list // Then, preserve existing e-tags for eventIds we're keeping
// Note: We can't easily check if an a-tag represents a specific event ID without resolving it for (const eventId of deduplicatedEventIds) {
// So we'll add e-tags for all eventIds, and rely on clients to prefer a-tags when resolving if (existingETags.has(eventId)) {
const seenETags = new Set<string>(); // Preserve the full existing e-tag (with relay hints, etc.)
const existingETag = existingETags.get(eventId)!;
tags.push(existingETag);
seenEventIds.add(eventId);
}
}
// Finally, add new simple e-tags for newly added eventIds
for (const eventId of deduplicatedEventIds) { for (const eventId of deduplicatedEventIds) {
if (!seenETags.has(eventId)) { if (!seenEventIds.has(eventId)) {
tags.push(['e', eventId]); tags.push(['e', eventId]);
seenETags.add(eventId); seenEventIds.add(eventId);
} }
} }
// Final deduplication: if we somehow have duplicate e-tags, remove them // Final deduplication: if we somehow have duplicate e-tags, remove them
// (This shouldn't happen, but ensures clean output) // (This shouldn't happen, but ensures clean output)
const finalTags: string[][] = []; const finalTags: string[][] = [];
const seenEventIds = new Set<string>(); const seenFinalEventIds = new Set<string>();
for (const tag of tags) { for (const tag of tags) {
if (tag[0] === 'a') { if (tag[0] === 'a') {
@ -272,9 +280,9 @@ async function publishPinList(eventIds: string[]): Promise<{ success: string[];
// If an a-tag represents this event, we'd ideally skip the e-tag, // If an a-tag represents this event, we'd ideally skip the e-tag,
// but we can't check that without resolving a-tags // but we can't check that without resolving a-tags
// So we'll keep the e-tag and let clients handle the preference // So we'll keep the e-tag and let clients handle the preference
if (!seenEventIds.has(tag[1])) { if (!seenFinalEventIds.has(tag[1])) {
finalTags.push(tag); finalTags.push(tag);
seenEventIds.add(tag[1]); seenFinalEventIds.add(tag[1]);
} }
} else { } else {
// Keep other tag types as-is // Keep other tag types as-is
@ -383,29 +391,37 @@ async function publishBookmarkList(eventIds: string[]): Promise<{ success: strin
return { success: [], failed: [] }; // No changes, cancel operation return { success: [], failed: [] }; // No changes, cancel operation
} }
// Build final tags: preserve all a-tags, add/update e-tags // Build final tags: preserve all a-tags, preserve existing e-tags, add new e-tags
const tags: string[][] = []; const tags: string[][] = [];
const seenEventIds = new Set<string>();
// First, add all existing a-tags (they take precedence) // First, add all existing a-tags (they take precedence)
for (const aTag of existingATags) { for (const aTag of existingATags) {
tags.push(aTag); tags.push(aTag);
} }
// Then, add e-tags for all event IDs in the final list // Then, preserve existing e-tags for eventIds we're keeping
// Note: We can't easily check if an a-tag represents a specific event ID without resolving it for (const eventId of deduplicatedEventIds) {
// So we'll add e-tags for all eventIds, and rely on clients to prefer a-tags when resolving if (existingETags.has(eventId)) {
const seenETags = new Set<string>(); // Preserve the full existing e-tag (with relay hints, etc.)
const existingETag = existingETags.get(eventId)!;
tags.push(existingETag);
seenEventIds.add(eventId);
}
}
// Finally, add new simple e-tags for newly added eventIds
for (const eventId of deduplicatedEventIds) { for (const eventId of deduplicatedEventIds) {
if (!seenETags.has(eventId)) { if (!seenEventIds.has(eventId)) {
tags.push(['e', eventId]); tags.push(['e', eventId]);
seenETags.add(eventId); seenEventIds.add(eventId);
} }
} }
// Final deduplication: if we somehow have duplicate e-tags, remove them // Final deduplication: if we somehow have duplicate e-tags, remove them
// (This shouldn't happen, but ensures clean output) // (This shouldn't happen, but ensures clean output)
const finalTags: string[][] = []; const finalTags: string[][] = [];
const seenEventIds = new Set<string>(); const seenFinalEventIds = new Set<string>();
for (const tag of tags) { for (const tag of tags) {
if (tag[0] === 'a') { if (tag[0] === 'a') {
@ -416,9 +432,9 @@ async function publishBookmarkList(eventIds: string[]): Promise<{ success: strin
// If an a-tag represents this event, we'd ideally skip the e-tag, // If an a-tag represents this event, we'd ideally skip the e-tag,
// but we can't check that without resolving a-tags // but we can't check that without resolving a-tags
// So we'll keep the e-tag and let clients handle the preference // So we'll keep the e-tag and let clients handle the preference
if (!seenEventIds.has(tag[1])) { if (!seenFinalEventIds.has(tag[1])) {
finalTags.push(tag); finalTags.push(tag);
seenEventIds.add(tag[1]); seenFinalEventIds.add(tag[1]);
} }
} else { } else {
// Keep other tag types as-is // Keep other tag types as-is
@ -576,13 +592,15 @@ async function publishMuteList(pubkeys: string[]): Promise<void> {
// Collect existing p tags // Collect existing p tags
const existingPubkeys = new Set<string>(); const existingPubkeys = new Set<string>();
const existingPTags: string[][] = []; // Store full p tags to preserve relay hints and petnames
if (existingLists.length > 0) { if (existingLists.length > 0) {
const existingList = existingLists[0]; const existingList = existingLists[0];
for (const tag of existingList.tags) { for (const tag of existingList.tags) {
if (tag[0] === 'p' && tag[1]) { if (tag[0] === 'p' && tag[1]) {
existingPubkeys.add(tag[1]); existingPubkeys.add(tag[1]);
} existingPTags.push(tag);
}
} }
} }
@ -594,10 +612,23 @@ async function publishMuteList(pubkeys: string[]): Promise<void> {
return; // No changes, cancel operation return; // No changes, cancel operation
} }
// Build final tags: all p tags for muted pubkeys // Build final tags: preserve existing p tags for pubkeys we're keeping, add new ones
const tags: string[][] = []; const tags: string[][] = [];
const seenPubkeys = new Set<string>();
// First, add existing p tags for pubkeys we're keeping
for (const tag of existingPTags) {
if (tag[1] && deduplicatedPubkeys.includes(tag[1])) {
tags.push(tag);
seenPubkeys.add(tag[1]);
}
}
// Then, add new p tags for pubkeys we're adding (without relay hints or petnames)
for (const pubkey of deduplicatedPubkeys) { for (const pubkey of deduplicatedPubkeys) {
tags.push(['p', pubkey]); if (!seenPubkeys.has(pubkey)) {
tags.push(['p', pubkey]);
}
} }
// Create new mute list event // Create new mute list event

Loading…
Cancel
Save