FEP-c0e0: Emoji reactions

I have never ever seen an emoji reaction feature on any social media platform that, subsequent to reacting with an emoji, asks you to choose whether that emoji reaction was positive, negative or neutral.

We do have like and dislike as possible activities. So like already said above, we have to decide about the expected behaviour of system that don’t support it. Should they ignore it, then some EmojiReact would be the best. Otherwise using a Like as container would be nice, since this can be processed by each system - but then I really would be in favour of some positive/negative mappong, since we should transmit negative emojis as a Dislike.

As I said above, I think it is best to ignore it. I feel it is better to ignore it than to risk misunderstanding an emoji reaction like :rage: or :-1: as a positive like.

I think trying to create some kind of mapping from Emoji → Positive/Neutral/Negative sentiment is an extremely bad idea. As I said above:

  1. This is not a trivial mapping to create.
  2. Different implementations may disagree about the mapping.
  3. Different cultures may disagree about the sentiment of emojis.
  4. Emojis may be used in different contexts with entirely different sentiments that are impossible to decide without the user explicity deciding the sentiment themselves (and forcing the user to make this choice is a non-starter).

In short, you cannot boil down emojis to a simple Positive/Neutral/Negative sentiment. It simply makes no sense.

And again, if for some reason your implementation decides to treat a :+1: reaction as a like, then you can just send an additional Like activity to signify that (without requiring the user to do anything). The implementations that support both emojis and likes will process both and the ones that only support likes will just see the like. I really don’t see a need to mix the concepts together.

Sending both a Like and an Emojirect would be a bad idea, as we would then need a mechanism to suppress the Like on those systems.

I haven’t quite managed to motivate myself to make a comprehensive write-up yet (stupid procrastination!), but to give a quick response, it’s not that I deny the utility of Dislike activities. I might’ve been biased toward the microblogosphere, where the Dislike activity isn’t quite popular, but that at least exemplifies the use case where falling back to interpretation as Like is useful. (Or I’d argue that it’s vital rather than useful for Misskey to communicate with implementations with no reactions support, because it doesn’t have a counterpart of Mastodon’s “favourite”, and reactions are the only lightweight and structured means of expressing positive feedback.)

Also, the “value judgement” you quoted is primarily intended as an implementation policy, which I think is orthogonal to whatever of the ActivityPub protocol. EmojiReact and Like with content can (and do already) coexist as you mentioned, and an implementation only adopting the latter doesn’t prevent other implementations from adopting the former.

1 Like

I don’t understand - why would you need that? Could you elaborate?

As an outsider who’s only recently learned about ActivityPub, the more I learn about it, the more it seems biased towards microblogging applications. I guess it shouldn’t be surprising with Mastodon being a huge influence but it’s still a bit discouraging to see as someone who has never really had an interest in microblogging platforms.

When someone sends both a Like and an EmojiReact then you would see both activities here:
grafik
One at right side with the Emoji and one where we display the Like activities. This would be wrong, since it would appear that there had been two reactions, but there was only one. So we would need to filter by actor and would accept only a single activity per actor.

I see what you mean, but wouldn’t that be the same if you were to use Dislike and Like to contain a positive/negative reaction?

I mean if you get a Dislike activity with a :face_with_diagonal_mouth: content field, would you not interpret that as both a dislike/downvote (the black :-1: on your picture) and a :face_with_diagonal_mouth: reaction?

If not, I suppose you would only treat it as a :face_with_diagonal_mouth: reaction? But then on another implementation that doesn’t support emoji reactions, you’d see a dislike/downvote and obviously no reaction. Isn’t that a bit confusing? On one platform you’d see a user reacting with :face_with_diagonal_mouth: (with no vote up or down) and on another platform you’d see the same user downvoting/disliking the same post?

I would personally find such behaviour kind of strange. I think it’d be less confusing if the dislike/downvote on the non-supporting platform simply wouldn’t be there - it doesn’t support emoji reactions so the emoji reaction is obviously not there - that makes sense.

Misskey sends their emojis via Like activities. When we detect that the Like contains a Unicode payload, then we display it only as an emoji reaction and not as a like. So if we would map all emojis according to their mood (which is a job, that I wouldn’t want to do), then all receivers that can distinguish between Like and Dislike activities would always see at least the mood (either positive or negative) and all receivers that can display emojis would see a reaction that is more detailed.

BTW: We have got the same problem when we would use the mechanism that you suggested to send two activities (one Like, one EmojiReact).

I’ve got the impression as if we need some capabilities functionality, so that we would only send emoji reactions to systems that support them.

Yes, but then the problem is only contained to the implementations that choose to do it that way. My real point is that we should use a separate, distinct activity such as EmojiReact and not muddling them with Likes, but of course any implementation can choose to send both Like and EmojiReact if they think that makes sense. Personally, if I were to implement it, I would not send both a Like and EmojiReact, but another implementation could choose differently. Separating the activities gives more choice to the individual implementation in that way, I feel.

That would be useful yea. Isn’t there already some FEP for something like that?

I don’t know if there is already an FEP for capabilities. I never wrote an FEP and I mostly only have got a look at them, when someone points me to it or I find it by accident.

Ah I think I was just thinking of this one but it’s not quite the same.

Again, mapping emojis to like/dislike is backwards thinking. You start by letting the user select Like/Dislike first, then optionally adding arbitrary content which might be a single emoji. So in UI you might express this iconographically as :+1: / :-1: / :heavy_plus_sign: (or using arrows instead of thumbs, etc)

Your client could then send the Like or Dislike, and then if the content is a single emoji, also send an EmojiReact. Or it could be constructed as a multityped activity that is both a Like and an EmojiReact, provided that EmojiReact is defined with parallel structure to a Like (i.e. using object and content)

The risk is overfitting a protocol to specific UX abstractions that don’t make sense for everyone. That’s what I call a leaky abstraction. The semantic meaning needs to be clearly defined first.

It may be unavoidable if the semantics differ significantly enough to justify EmojiReact being a separate activity. But this doesn’t necessitate them being two separate activites – if they share object and content then it could be represented as a single multityped activity.

It should be both. ActivityPub specifies that Like activites should trigger side effects of being added to the likes collection. This is separate from emoji reactions existing or not.

This could be done simply by checking for presence of a collection property. If the object has a replies collection then it probably supports receiving replies. same for likes and shares. having an emojiReactions collection would work similarly – just check for its presence.

What if I don’t want to make the user select Like or Dislike first? For instance, separate buttons with “Upvote” (like), “Downvote” (dislike) and “React” labels? I mean you say we shouldn’t overfit to a single UX and I definitely agree, but forcing the selection of positive/negative (like/dislike) before being able to use an emoji reaction is exactly that kind of overfitting I would say.

I also want to highlight that users should obviously be able to react multiple times with different emojis (or maybe even multiple times with the same emoji, though I would imagine most implementations would not allow this, just as multiple likes are not allowed) and multiple emoji reactions should not influence whether I have Liked or Disliked the post.

Which systems publish a likes collection?

Hubzilla currently does not support outbound emoji reactions AFAIK. Maybe you got a regular note with just a custom emoji as content?

Yes, it was a regular note. I probably misunderstood then - someone in fediverse said that Hubzilla and Streams users send emoji reactions as replies and I thought this is a supported feature.

I’m not sure, but I’m saying that implementations should move toward this ideal. Right now we’re in a situation where impls mostly expect to always be able to reply/like/share, and they don’t actually care for / check / defer to these collections as “canonical”. instead, they are implicitly reconstructed based on all interactions the server is aware of.

What do you mean with:

Even when translated to German (my primary language) I don’t really understand what you mean with “canonical” and what you wanted to say.

Circling back to another thing… reusing litepub:EmojiReact and fedibird:emojiReactions or should we use new IRIs; in other words: are the existing semantics well-defined enough and correct enough?

IIRC there are some issues with current implementations which expect EmojiReact to always contain Unicode emoji and reject custom emoji, and there are also issues with whether the emojiReactions collection contains Likes vs only containing EmojiReacts. I think these issues are mostly sidesteppable, in that impls who don’t support custom emoji can drop those activities silently, and impls also get to decide arbitrarily which activities they serve in which collections. so it’s up to each impl to decide how “strict” it wants to comply. mostly this can be considered robustness and error handling.

1 Like

So “canonical” is basically having a single source of truth for the question, “what are all the replies/likes/etc to this post?”

Ideally, there would be a collection, and you would simply check the collection.

Instead, we currently look through the local cache/database for all posts we’re aware of containing inReplyTo, for example for replies. We never actually care to check for a replies collection or its contents. If we did, it would solve a lot of things: controls, capabilities, approvals, syncing, and so on would be a lot simpler if we had a canonical collection to check, a single source of truth.