Updates to extensions for Lysand 1.1

This commit is contained in:
Jesse Wierzbinski 2024-03-19 15:06:16 -10:00
parent a55283bc8c
commit c82af6ab4c
No known key found for this signature in database
5 changed files with 149 additions and 97 deletions

View file

@ -83,3 +83,13 @@ These include:
- [Is Cat](/extensions/is-cat) - [Is Cat](/extensions/is-cat)
- [Server Endorsement](/extensions/server-endorsement) - [Server Endorsement](/extensions/server-endorsement)
- [Reports](/extensions/reports) - [Reports](/extensions/reports)
## Types
```typescript
// Specific extension types will extend from this
interface Extension extends Entity {
type: "Extension";
extension_type: string;
}
```

View file

@ -1,6 +1,6 @@
# Custom Emojis # Custom Emojis
Please see [Custom Emojis](/structures/custom-emoji) for more information about the Custom Emojis type. The extension is implemented as such: For detailed information about the Custom Emoji type, refer to [Custom Emojis](../structures/custom-emoji). The implementation of the extension is as follows:
```json5 ```json5
{ {
@ -10,12 +10,12 @@ Please see [Custom Emojis](/structures/custom-emoji) for more information about
"emojis": [ "emojis": [
{ {
"name": "happy_face", "name": "happy_face",
"url": [ "url": {
{ "image/png": {
"content": "https://cdn.example.com/emojis/happy_face.webp", "content": "https://cdn.example.com/emojis/happy_face.png",
"content_type": "image/webp" "content_type": "image/png"
}
} }
]
}, },
// ... // ...
] ]
@ -25,34 +25,33 @@ Please see [Custom Emojis](/structures/custom-emoji) for more information about
} }
``` ```
That is, the extension name is `org.lysand:custom_emojis`, and the extension value is an object that contains a list of emojis. In this context, the extension name is `org.lysand:custom_emojis`, and the extension value is an object that includes an array of emojis.
## Applying Custom Emojis ## Utilizing Custom Emojis
Clients **MUST** apply custom emojis to the following fields of the following objects: Clients are **required** to implement custom emojis in any text field where their presence is plausible. This includes, but is not limited to, status text, display names, alt text, and bio fields. However, this does not extend to an [Actor](../objects/actors)'s username, for instance.
- `Publication.contents` A custom emoji is represented within a text string as follows:
- `Publication.subject`
- `Actor.bio`
- `Actor.display_name`
A custom emoji is formatted inside a text string as follows:
``` ```
:emoji_name: :emoji_name:
``` ```
For example, if a user wants to use the `happy_face` emoji, they would type: For instance, to use the `happy_face` emoji, a user would type:
``` ```
:happy_face: :happy_face:
``` ```
Clients **MUST** replace the `:emoji_name:` with the appropriate emoji. If the client does not support custom emojis, it **SHOULD** display the `:emoji_name:` as-is. Clients are **required** to substitute the `:emoji_name:` with the corresponding inline emoji. If the client does not support custom emojis, it **should** display the `:emoji_name:` as it is.
If the client supports Custom Emojis, but does not support the emoji that the user is trying to use (such as with an incompatible MIME type), it **SHOULD** display the `:emoji_name:` as-is. If the client supports Custom Emojis, but does not support a specific emoji that the user is attempting to use (such as with an incompatible MIME type), it **should** display the `:emoji_name:` as it is.
When rendered as images, Custom Emojis **SHOULD** have proper alt text for accessibility. The alt text **SHOULD** be the alt text of the emoji, if it has one. If the emoji does not have an alt text, the alt text **SHOULD** be the name of the emoji. When rendered as images, Custom Emojis **should** have appropriate alt text for accessibility. The alt text **should** be the alt text of the emoji, if it exists. If the emoji does not have an alt text, the alt text **should** be the name of the emoji.
### Styling Custom Emojis
If the styling system, such as CSS, supports it, clients **should** style the emoji to match the height of the text but allow it to take as much width as necessary, instead of treating it as a square and potentially distorting the image.
Example in HTML: Example in HTML:
```html ```html
Hello, world! <img src="https://cdn.example.com/emojis/happy_face.webp" alt="A happy face emoji." title="A happy face emoji."> Hello, world! <img src="https://cdn.example.com/emojis/happy_face.webp" alt="A happy face emoji." title="A happy face emoji." style="display: inline; height: 1em;">
``` ```

View file

@ -1,10 +1,14 @@
# IsCat # IsCat
> **Note:** This is a **silly** extension that is not meant to be taken very seriously. > [!NOTE]
> This is a **light-hearted** extension designed for amusement and not intended for serious application.
With the Is Cat extension, users can tell other users if they are a cat or not. This is akin to Misskey's "IsCat" feature. > [!WARNING]
> This extension may be superseded by the upcoming [Vanity Profiles](./vanity) extension.
An Actor can indicate whether they are a cat or not with the following field: The IsCat feature allows users to communicate their cat status to others, similar to Misskey's "IsCat" feature.
A user, referred to as an Actor, can specify their feline status using the following field:
```json5 ```json5
{ {
@ -12,10 +16,12 @@ An Actor can indicate whether they are a cat or not with the following field:
// ... // ...
"extensions": { "extensions": {
"org.lysand:is_cat": { "org.lysand:is_cat": {
"cat": true "cat": true,
// Potential additional fields
// "dog": true
} }
} }
} }
``` ```
Clients **SHOULD** render some graphic to indicate if a user is a cat or not, such as cat ears on the user's avatar. Clients **SHOULD** display an appropriate graphic to signify a user's cat status, such as adding cat ears to the user's avatar.

View file

@ -1,34 +1,33 @@
# Polls # Polls
With the Polls extension, users can create polls. This is useful for asking questions to users, such as "What is your favourite colour?". The Polls extension enables users to generate polls/surveys, a valuable tool for soliciting feedback or opinions from users, such as "What is your preferred color?".
Polls are added as a new field under Publication Extensions, called `poll`. This field is an object that contains the poll information. Polls are incorporated as a new field under the [Note](../objects/note) Extensions, named `polls`. This field is an object that encapsulates the poll details.
```json5 ```json5
{ {
"id": "f08a124e-fe90-439e-8be4-15a428a72a19",
"type": "Note",
// ... // ...
"extensions": { "extensions": {
"org.lysand:polls": { "org.lysand:polls": {
"poll": { "poll": {
"options": [ "options": [
[
{ {
"content": "Red", "text/plain": {
"content_type": "text/plain" "content": "Red"
} }
], },
[
{ {
"content": "Blue", "text/plain": {
"content_type": "text/plain" "content": "Blue"
} }
], },
[
{ {
"content": "Green", "text/plain": {
"content_type": "text/plain" "content": "Green"
}
} }
]
], ],
"votes": [ "votes": [
9, 9,
@ -44,45 +43,59 @@ Polls are added as a new field under Publication Extensions, called `poll`. This
} }
``` ```
These fields are described below. The fields are explained below.
> **Note:** There is no `question` field, because it is assumed that the question will be put in the `contents` field of the Publication. Clients are expected to render polls next to the contents of the Publication itself. > [!NOTE]
> There is no `question` field, as it is presumed that the question will be included in the `contents` field of the associated [Note](../objects/note). Clients are anticipated to render surveys adjacent to the contents of the [Note](../objects/note) itself.
## Fields ## Fields
### Options ### Options
The `options` field on a Poll object is an array that contains a list of `ContentFormat` arrays. It is used to represent the options of the poll. | Name | Type | Required |
| :------ | :--------------------- | :------- |
| options | Array of ContentFormat | Yes |
The `options` field is required on all Poll extension fields Displays the various options users can vote for.
The `options` field **MUST** contain at least 2 options, and does not have an upper limit for the number of options. **MUST** contain at least 2 options, but does not have an upper limit for the number of options.
> **Note:** Servers should limit the number of options to a reasonable number, perferably in a configurable manner, such as 10. This is to prevent abuse of the protocol by sending a large number of options. > [!NOTE]
> Servers should limit the number of options to a reasonable number, preferably in a configurable manner, such as 40. This is to prevent abuse of the protocol by sending a large number of options, as they are not paginated.
### Votes ### Votes
The `votes` field on a Poll object is an array that contains a list of integers. It is used to represent the number of votes for each option. | Name | Type | Required |
| :---- | :--------------- | :------- |
| votes | Array of Integer | Yes |
The `votes` field is required on all Poll extension fields. Contains the number of votes cast for each option. The index of the array corresponds to the index of the option in the `options` array.
Votes should not be public: the server should hide the users that casted votes and only show the total amount.
### Multiple Choice ### Multiple Choice
The `multiple_choice` field on a Poll object is a boolean that represents whether or not the poll is multiple choice. It is used to determine if the user can select multiple options. | Name | Type | Required |
| :-------------- | :------ | :------- |
| multiple_choice | Boolean | No |
The `multiple_choice` field is not required on all Poll extension fields. If it is not provided, it is assumed that the poll is not multiple choice. Indicates whether the poll is multiple choice. If true, users can vote for multiple options. If false, users can only vote for one option.
### Expires At If not provided, it is assumed that the poll is not multiple choice.
The `expires_at` field on a Poll object is a string that represents the date and time that the poll expires. It is used to determine when the poll ends, and when to stop accepting votes. ### Expiration
The `expires_at` field is required on all Poll extension fields. | Name | Type | Required |
| :--------- | :----- | :------- |
| expires_at | String | Yes |
The date and time when the poll expires. After this time, the poll is closed and no more votes can be cast.
Clients **SHOULD** display the time remaining until the poll expires. Clients **SHOULD** display the time remaining until the poll expires.
### Integration With Custom Emojis ### Integration With Custom Emojis
If you implement both the Polls and the Custom Emojis extensions, you can use the Custom Emojis extension to add emojis to poll options. If you implement both the Polls and the [Custom Emojis](./custom-emojis) extensions, you can use the Custom Emojis extension to add emojis to poll options.
Example: Example:
```json5 ```json5
@ -92,24 +105,21 @@ Example:
"org.lysand:polls": { "org.lysand:polls": {
"poll": { "poll": {
"options": [ "options": [
[
{ {
"content": ":red:", "text/plain": {
"content_type": "text/plain" "content": "Red :red:"
} }
], },
[
{ {
"content": ":blue:", "text/plain": {
"content_type": "text/plain" "content": "Blue :blue:"
} }
], },
[
{ {
"content": ":green:", "text/plain": {
"content_type": "text/plain" "content": "Green :green:"
}
} }
]
], ],
"votes": [ "votes": [
9, 9,
@ -124,30 +134,27 @@ Example:
"emojis": [ "emojis": [
{ {
"name": "red", "name": "red",
"url": [ "url": {
{ "image/webp": {
"content": "https://cdn.example.com/emojis/red.webp", "content": "https://cdn.example.com/emojis/red.webp"
"content_type": "image/webp" }
} }
]
}, },
{ {
"name": "blue", "name": "blue",
"url": [ "url": {
{ "image/webp": {
"content": "https://cdn.example.com/emojis/blue.webp", "content": "https://cdn.example.com/emojis/blue.webp"
"content_type": "image/webp" }
} }
]
}, },
{ {
"name": "green", "name": "green",
"url": [ "url": {
{ "image/webp": {
"content": "https://cdn.example.com/emojis/green.webp", "content": "https://cdn.example.com/emojis/green.webp"
"content_type": "image/webp" }
} }
]
} }
] ]
} }
@ -156,19 +163,17 @@ Example:
} }
``` ```
When rendering the poll options, clients **SHOULD** display emojis as recommended by the [Custom Emojis](/extensions/custom-emojis) extension. When rendering the poll options, clients **SHOULD** display emojis as recommended by the [Custom Emojis](./custom-emojis) extension.
### Poll Results ### Poll Results
Clients **SHOULD** display poll results as a percentage of votes. For example, if 10 users voted for the first option, and 5 users voted for the second option, the first option should be displayed as 66.67%, and the second option should be displayed as 33.33%. Clients **SHOULD** display poll results as a percentage of votes. For example, if 10 users voted for the first option, and 5 users voted for the second option, the first option should be displayed as 66.67%, and the second option should be displayed as 33.33%. (with the third option being 0%)
Clients **SHOULD** display the number of votes for each option. Clients **SHOULD** display the number of votes for each option, and the total number of votes.
Clients **SHOULD** display the total number of votes.
### Sending Votes ### Sending Votes
Clients **SHOULD** allow users to vote on polls. When a user votes on a poll, the client **MUST** send a `POST` request to the poll's Publication URI with the following JSON object in the body: Clients **SHOULD** allow users to vote on polls. When a user votes on a poll, the client **MUST** send a `POST` request to the poll's [Note](../objects/note) URI with the following JSON object in the body:
```json5 ```json5
{ {
@ -182,7 +187,9 @@ Clients **SHOULD** allow users to vote on polls. When a user votes on a poll, th
} }
``` ```
In return, the server **MUST** respond with a `200 OK` response code, and a JSON object in the body. This JSON object **MUST** be a valid `VoteResult` object. The `option` field **MUST** be the index of the option in the `options` array that the user is voting for.
In return, the server **MUST** respond with a `200 OK` response code, and a JSON object in the body, unless there is an error. This JSON object **MUST** be a valid `VoteResult` object.
```json5 ```json5
{ {
@ -199,6 +206,8 @@ In return, the server **MUST** respond with a `200 OK` response code, and a JSON
} }
``` ```
Each number in the `votes` array corresponds to the number of votes for each option. The index of the array corresponds to the index of the poll option in the original Poll object.
If the poll is closed, the server **MUST** respond with a `403 Forbidden` response code. If the poll is closed, the server **MUST** respond with a `403 Forbidden` response code.
The total amount of votes can be calculated by summing the `votes` array. The total amount of votes can be calculated by summing the `votes` array.
@ -210,3 +219,31 @@ This amount **MUST** include the user's vote, and **SHOULD** be displayed to the
When a poll ends, a user that has voted in it **SHOULD** be notified of the results by the server. When a poll ends, a user that has voted in it **SHOULD** be notified of the results by the server.
The server **MAY** send a `GET` request to the poll's Publication URI to update its internal database. The server **MAY** send a `GET` request to the poll's Publication URI to update its internal database.
## Types
```typescript
interface Poll extends Extension {
extension_type: "org.lysand:polls/Poll";
options: ContentFormat[];
votes: number[];
multiple_choice?: boolean;
expires_at: string;
}
```
```typescript
interface Vote extends Extension {
extension_type: "org.lysand:polls/Vote";
poll: string;
option: number;
}
```
```typescript
interface VoteResult extends Extension {
extension_type: "org.lysand:polls/VoteResult";
poll: string;
votes: number[];
}
```

View file