nostr-protocol / nips

Nostr Implementation Possibilities
2.39k stars 582 forks source link

Feature Tracker: Edits #1569

Open staab opened 2 weeks ago

staab commented 2 weeks ago

Just a list of PRs that propose some version of note editing:

https://github.com/nostr-protocol/nips/pull/1087 https://github.com/nostr-protocol/nips/pull/1088 https://github.com/nostr-protocol/nips/pull/1089 https://github.com/nostr-protocol/nips/pull/1090 https://github.com/nostr-protocol/nips/pull/1091 https://github.com/nostr-protocol/nips/pull/1556 https://github.com/nostr-protocol/nips/pull/1565

Also relevant:

https://github.com/nostr-protocol/nips/pull/1510 https://github.com/nostr-protocol/nips/pull/1540

staab commented 2 weeks ago

My take is that of all the edit proposals, I like Vitor's #1090 the best, since it is simple, and provides the ability for clients to show a complete history of changes. However, it comes at the very significant cost of increasing the barrier to entry for kind-1 clients, which are a kind of schelling point for nostr. I would like to see developers attempt to solve the UX issues using #1091 and delayed-send "undo" before adding more complexity to the protocol.

melvincarvalho commented 2 weeks ago

Agreed, #1090 is the simplest and looks best. Not sure the second half on collaboration is even needed, but I don't see any harm in keeping it.

arthurfranca commented 2 weeks ago

With the nip-22 merge as-is (regular non-addressable event) i would say its safe to consider solutions using addressable events (#1087, #1088, #1089, #1510, #1540 and #1565) ruled out in favor of simpler approaches that extend a regular non-editable event.

PR Good Bad
#1090 1) non-supporting clients don't change anything;
2) supports inlined annotations
1) non-supporting clients don't see edits, favoring centralization on supporting clients
#1091 1) non-supporting clients don't change anything;
2) they see annotations as replies
1) not really edits;
2) small improvement over simply pushing OP replies to the top
#1556 1) non-supporting clients don't change anything;
2) supporting clients may recover reset engagement (replies etc, using s tag)
1) resets engagement (recoverable with added complexity);
2) ~edits go to the top of chronological feed if editing a root note~in fact, not if using same .created_at

Didn't add bad points applicable to all of them for not being addressable events nor the good points for being regular events.

fiatjaf commented 2 weeks ago

What if annotations included a string like s/old_text/new_text/ that could then be replaced in the original event together with a comment? That would perform actual edits, but also notify users of the edits explicitly -- and would naturally limit the scope and size of the edit. For example:

EDIT: fixed some typos.

s/ehllo/hello/
s/wrldo/world/

or

EDIT: fixed my sentiment towards dogs

s/love/hate/

(This is not a finished idea, of course.)

staab commented 2 weeks ago

What does that improve other than slightly reduce payload size? It just seems to increase the complexity and make clients do more busywork. I guess you could show a diff, but you could do that with full replace too.

fiatjaf commented 2 weeks ago

I'm just thinking that if on every edit you were forced to add a message at the bottom of the original event then clients and users would naturally limit the size of those edits.

Like the guy who edited an event 140+ times would soon realize that he was doing something wrong (and would write a kind:30023 article instead, which is what he should have done in the first place).

If people like this idea we could perhaps specify in the NIP the amount of characters that can be replaced such that edits are readable for those without compliant clients.

But I'm not sure this is a good idea anyway.

ekzyis commented 2 weeks ago

What does that improve other than slightly reduce payload size? It just seems to increase the complexity and make clients do more busywork. I guess you could show a diff, but you could do that with full replace too.

I think the point was that this would allow full edits but still show up as normal replies on unaware clients.

This sed syntax might not be it yet but it gives me hope that a reconciliation of #1090 and #1091 is indeed possible as mentioned by @alltheseas in https://github.com/nostrability/nostrability/issues/118#issuecomment-2442627757 and in @fiatjaf's post:

Eventually we could have annotations that are expressed in form of simple (human-readable?) diffs that can be applied directly to the post, but fall back, again, to comments.


I would like to see developers attempt to solve the UX issues using https://github.com/nostr-protocol/nips/pull/1091 and delayed-send "undo" before adding more complexity to the protocol.

I have come along thanks to @fiatjaf's post and the discussions here and here and I think this is indeed a good compromise to see if we even need a spec for this. On SN, we only have edits for 10 minutes and that seems to work fine except for bigger posts where users want infinite edits. But for this use case, nostr has kind:30032 already.

fiatjaf commented 1 week ago

The point about kind:30023 is important, as all use cases I've seen of these "big edits I want to edit everything I love edits" users are actually confused people who want to write long articles and update them as months pass. It's completely unnecessary to use kind:1 for that, these things are not even showing up on feeds after their 44th edit 3 months after the initial post and that is just screwing everybody for no reason. We could just make them use kind:30023.

On the other side there are the typos people who love to fix their own typos and these would be made whole by delayed send and/or something like the sed annotations.

Of course people who just want to "clarify a thing" should be super happy with normal annotations.

arthurfranca commented 1 week ago

Instead of any of these proposolas, we could guide devs to: 1) warn users upon clicking "edit" that reactions and replies are gonna reset 2) "edit" by doing kind:5 followed by new kind:1 with same .created_at value from the original kind:1