w3c / activitystreams

Activity Streams 2.0
https://www.w3.org/TR/activitystreams-core/
Other
285 stars 60 forks source link

Feature similar to ostatus:conversation #476

Open evanp opened 6 years ago

evanp commented 6 years ago

We should be able to associate a big thread for conversation

evanp commented 6 years ago

So, this is used in OStatus for big hierarchical conversations. So when you have Notes like this:

Here, Note6 is inReplyTo Note5, and Note10 is inReplyTo Note9. But it's not clear that they are part of a larger conversation, unless you walk up the tree.

A conversation property links them all together. I think that most OStatus implementations use the ID of the root object (which is inReplyTo nothing else) as the conversation identifier, but I don't think they are required to.

evanp commented 6 years ago

So, related features we already have in AS2:

evanp commented 6 years ago

One thing we could do is define a Conversation type, and use it like this:

{
  "type": "Note",
  "id": "https://an.example/note/6",
  "inReplyTo": "https://an.example/note/5",
  "context": {
    "type": "Conversation",
    "id": "https://an.example/conversation/1"
  }
}

Another is to specify a root or op item:

{
  "type": "Note",
  "id": "https://an.example/note/6",
  "inReplyTo": "https://an.example/note/5",
  "root": {
    "type": "Note",
    "id": "https://an.example/note/1"
  }
}

Or we could use a conversation property:

{
  "type": "Note",
  "id": "https://an.example/note/6",
  "inReplyTo": "https://an.example/note/5",
  "conversation": {
    "type": "Conversation",
    "id": "https://an.example/conversation/1"
  }
}
{
  "type": "Note",
  "id": "https://an.example/note/6",
  "inReplyTo": "https://an.example/note/5",
  "conversation": {
    "type": "Note",
    "id": "https://an.example/note/1"
  }
}
evanp commented 6 years ago

It's also worth noting that many systems use a flat commenting/replying hierarchy, so everything would be inReplyTo Note1.

nightpool commented 6 years ago

for the record, even though mastodon uses a flat commenting UX, posts still technically form a nested heiarchy. (and even in more flat system, it's more intuitive sometimes to have notes as in reply to the last note in the thread, not the root note)

On Wed, May 9, 2018, 1:44 PM Evan Prodromou notifications@github.com wrote:

It's also worth noting that many systems use a flat commenting/replying hierarchy, so everything would be inReplyTo Note1.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/w3c/activitystreams/issues/476#issuecomment-387819135, or mute the thread https://github.com/notifications/unsubscribe-auth/AAORV--5CXtuWUG2SVnOSgUURbzrmswNks5twyr9gaJpZM4T4icd .

cjslep commented 6 years ago

inReplyTo is not marked as a functional property (there can be more than one), so is it expected that single objects could be part of many conversations?

I am a fan of the extra properties!

However, what is the compelling reason to having a separate Conversation type, too? I could maybe see an argument for it being a (Ordered?) Collection of a list of IRIs to every object in the conversation, but I don't see the utility that extra abstraction layer brings and two major costs: putting an arbitrary logical grouping in the graph, and forcing everyone to adhere to it. Instead, it seems more straightforward for any new properties to point directly to the head object and let applications crawl as far down as they please with whatever caching/grouping they want to do.

strugee commented 6 years ago

@cjslep so say you have a conversation tree like in https://github.com/w3c/activitystreams/issues/476#issuecomment-387813503. In your UI you want to know if, say, note 6 and note 10 are associated with each other (which they are because they're both replies to replies to note 1). Normally you would be required to walk the entire tree to find that information, but with this extension you could determine that information in constant time.

Also remember that nobody's forced to use it - extensions are optional :P

cjslep commented 6 years ago

@strugee Yes, I agree, that can be accomplished with just the new properties referencing the IRI of the root node and comparing them. I like that. I just don't see a compelling need for a whole new Conversation type to embody this concept.

Also, in practice I am sure it is constant time with most people replying to 1 thread at a time. But theoretically, it is linear time with respect to the number of conversations the replies are in (since inReplyTo is not marked as functional).

gobengo commented 6 years ago

Don't think "Conversation" type is necessary. a Property whose range is Link would be sufficient for

{ "conversation": "https://conversation-url.com" }

I worked at a "conversation not comments" company for a long time. It's quite the overloaded term. I think inReplyToRoot would be a bit more clear and specific to what we're talking about here ('inReplyTo' relation-following as opposed to something else, root of tree data structure)

evanp commented 1 year ago

So, 5 years later, we have a number of solutions to this issue. Mastodon uses the ostatus:conversation property directly. Here's an example "toot" from Mastodon:

{
   "@context" : [
      "https://www.w3.org/ns/activitystreams",
      {
         "atomUri" : "ostatus:atomUri",
         "conversation" : "ostatus:conversation",
         "inReplyToAtomUri" : "ostatus:inReplyToAtomUri",
         "ostatus" : "http://ostatus.org#",
         "sensitive" : "as:sensitive",
         "toot" : "http://joinmastodon.org/ns#",
         "votersCount" : "toot:votersCount"
      }
   ],
   "atomUri" : "https://cosocial.ca/users/evan/statuses/110257163940796886",
   "attachment" : [],
   "attributedTo" : "https://cosocial.ca/users/evan",
   "cc" : [
      "https://cosocial.ca/users/evan/followers"
   ],
   "content" : "<p>Why: temp rise under 1.5C</p><p>What: zero emissions by 2050; capture CO2</p><p>How to get to zero: vote and donate to climate+ pols, electric or no car, trains not planes, clean electricity or home solar, low or no meat, buy climate+</p><p>How to capture: plant 500 billion trees</p>",
   "contentMap" : {
      "en" : "<p>Why: temp rise under 1.5C</p><p>What: zero emissions by 2050; capture CO2</p><p>How to get to zero: vote and donate to climate+ pols, electric or no car, trains not planes, clean electricity or home solar, low or no meat, buy climate+</p><p>How to capture: plant 500 billion trees</p>"
   },
   "conversation" : "tag:cosocial.ca,2023-04-25:objectId=483056:objectType=Conversation",
   "id" : "https://cosocial.ca/users/evan/statuses/110257163940796886",
   "inReplyTo" : null,
   "inReplyToAtomUri" : null,
   "published" : "2023-04-25T02:46:47Z",
   "replies" : {
      "first" : {
         "items" : [],
         "next" : "https://cosocial.ca/users/evan/statuses/110257163940796886/replies?only_other_accounts=true&page=true",
         "partOf" : "https://cosocial.ca/users/evan/statuses/110257163940796886/replies",
         "type" : "CollectionPage"
      },
      "id" : "https://cosocial.ca/users/evan/statuses/110257163940796886/replies",
      "type" : "Collection"
   },
   "sensitive" : false,
   "summary" : null,
   "tag" : [],
   "to" : [
      "https://www.w3.org/ns/activitystreams#Public"
   ],
   "type" : "Note",
   "url" : "https://cosocial.ca/@evan/110257163940796886"
}

I believe other implementations use the context property for something similar. I think the best resolution here is to create a page at https://www.w3.org/wiki/Activity_Streams/Primer/Conversation and collect best practices.

Right now, I agree with @cjslep that the best way to do this is with a context property that links to the original post:

"context": {
    "type": "Note",
    "id": "https://an.example/note/1"
}
trwnh commented 1 year ago

Rather than linking to the original post, it would be better to have an explicit collection that can be managed by a mechanism similar to FEP-7888