This proposal describes an ActivityPub extension to allow actors to publish a short status text, with optional expiration, link attachment, and history.
Some centralized communication services provide their users with the ability to set a status on their account, which is usually displayed on their profile and sometimes next to their name in other places in the UI. These are distinct from regular posts because they can not be interacted with in any way whatsoever, can’t contain media attachments, and usually have a short character limit on the order of several hundred characters at most. Statuses are always visible to anyone who can see the actor itself.
9 Likes
I like the idea of statuses, but this seems needlessly restrictive.
- Why should I not be able to like or reply to a status?
- Why should I not be able to put a picture in a status?
- Why should I not be able to post a long status?
I don’t see any reason why statuses should be more limited than any other ActivityPub content. The content can be truncated at the client-side if the client so desires, possibly with a way to view the full status by clicking on it for instance.
Because this FEP serves one particular UX use case and only that. Nothing less, nothing more. It’s of extreme importance that protocol extensions come with well-defined UX expectations. Otherwise it’s a recipe for a mess. The exact use case for this FEP is the statuses that existed in early Facebook and VKontante:
(note the “is excited…” part)
And, by extension, a “tagline” sort of thing that VKontakte introduced shortly after switching to microblogging (and still has, although through it got quite buried throughout the numerous redesigns):
(“Случайностей не бывает” under the name)
I also drew some inspiration from the current Discord and GitHub implementations of a similar feature, because it is similar enough both in the form and in the spirit.
If you want to display a longer-form piece of content that can contain media attachments and can be interacted with by others on your profile, we already have that — it’s a regular post, a Note
, pinned on your profile.
For that to work, the client needs to somehow understand that the status is incomplete in the first place.
1 Like
Internally the client would know the whole status - if it is too long, it would truncate it to a certain length in order to display it in a small fashion. That’s what I meant.
I personally think this is too niche and seeing more interaction would be nice, but you do you.
I like the idea and might implement this feature at some point. Here's a couple of questions and suggestions:
1. There are similarities between actor statuses and featured objects, represented by actor's featured
collection. Couldn't we re-use the existing mechanism? For example, ActorStatus
could be an item in a featured
collection instead of a new attribute of an actor. That would make actor statuses partially compatible with many existing services.
2. Are JSON producers and consumers expected to treat sm:ActorStatus
as equivalent to ActorStatus
?
3. I think sm:ActorStatus
objects should have an attributedTo
property.
4. A more idiomatic way to clear a status is Update{sm:ActorStatus}
activity that sets endTime
to a past date. Then the current status could be determined by endTime
alone.
@feps
No. Mixing different object types, especially those that appear in different places in the UI and/or the database, in one collection, is never a good idea in practice.
A clean compatibility break with all preexisting software is an explicit goal of the existence of this FEP. Again, clean UX is much more important to me than this kind of half-baked compatibility. Not seeing statuses at all is better than seeing them in places where they don’t belong, like the list of posts.
And as equivalent to http://smithereen.software/ns#ActorStatus
. I mean it’s JSON-LD. Some implementations get away with ignoring the -LD part, but it’s on them if anything breaks because of that.
That’s sensible.
But, logically, if we allow the status object to be mutable at all, even just that one field, that also opens the door to restoring statuses that have expired, or even making a past status “current” by updating its endTime
to a future date.
>Some implementations get away with ignoring the -LD part, but it's on them if anything breaks because of that.
The -LD part is optional in ActivityPub, even @context
is not required (it's a SHOULD in section 3. Objects of the specification). If you want those other forms to be supported, it would be better to make this requirement explicit in the FEP.
>But, logically, if we allow the status object to be mutable at all, even just that one field, that also opens the door to restoring statuses that have expired, or even making a past status "current" by updating its endTime to a future date.
You can disallow mutation of other fields and re-setting of endTime
. Similar to polls, which shouldn't be updated after the endTime
is reached.
@feps
So, uh, are you suggesting to replace one obvious activity with another non-obvious one with a side effect? What for? And sending the object again to unreference it is just weird? What if there isn’t a status history for this actor? Then it’s like sending a Delete
but including the entire object being deleted instead of just an ID.
I don’t understand what you’re trying to accomplish with this. I simply translated the actions that the user can take in the UI to AP activities, one-to-one. There’s no use to go roundabout with these things.
In short: there is no reliable way to get the current status.
- sm:status
is optional
- When it is present, the embedded status might be expired
- sm:statusHistory
is also optional
- When it's present, you can't iterate through items and find the current status, because what is specified by sm:status
is not correlated with endTime
This problem can be fixed by indicating the current status with the endTime
property (if the timestamp is in the future, the status is current). Then Update
would make sense.
@feps
It can’t and I don’t know how you came to this conclusion. It’s always the current status, the same one displayed on the profile. sm:status
is the reliable way to get the current status. You are never supposed to iterate anything unless you want to backfill your local copy of the status history.
This is written in the Actor fields section:
"sm:status
... SHOULD NOT be present if the last status has expired"
"SHOULD NOT" means sm:status
might be present if the referenced status has expired.
@feps
What do you mean, what is the “referenced status”?
The value of the sm:status
field.
If it's always the current status, how it can be expired? A different RFC-2119 key word would make sense there: "MUST NOT be present if the last status has expired". But I have no idea what any of that is supposed to mean. It's your text, after all, not mine.
@feps
It’s supposed to mean that sm:status
is the current status. It must be an inlined object (so no such thing as a “referenced status”). The field must not be there if the status has expired or if the actor has cleared it.
Yes I did write SHOULD when I meant MUST. Will fix.
1 Like
Thanks. I still think it would be nice to have a reverse property for Actor.status
(mutable ActorStatus.endTime
can work as reverse property), but it's not strictly necessary.
@feps