Download OpenAPI specification:Download
The pronouns.cc REST API
+Get a user object. Accepts either ID or username.
+userRef required | string A user reference, either an ID or a username. +IDs are always prioritized, if a user's username is the same as another user's ID, the user with that ID is returned. + |
{- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "member_title": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "value": "string",
- "status": "string"
}
], - "members": [
- {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "pronouns": "string",
- "display_text": "string",
- "status": "string"
}
]
}
], - "fields": [
- {
- "name": "string",
- "entries": [
- {
- "value": "string",
- "status": "string"
}
]
}
], - "custom_preferences": {
- "property1": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}, - "property2": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}
}
}
Get the user object associated with the provided token.
+{- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "member_title": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "value": "string",
- "status": "string"
}
], - "members": [
- {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "pronouns": "string",
- "display_text": "string",
- "status": "string"
}
]
}
], - "fields": [
- {
- "name": "string",
- "entries": [
- {
- "value": "string",
- "status": "string"
}
]
}
], - "custom_preferences": {
- "property1": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}, - "property2": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}
}, - "max_invites": 0,
- "is_admin": true,
- "list_private": true,
- "discord": "string",
- "discord_username": "string",
- "tumblr": "string",
- "tumblr_username": "string",
- "google": "string",
- "google_username": "string",
- "fediverse": "string",
- "fediverse_username": "string",
- "fediverse_instance": "string"
}
Update the current user.
+name | string [ 2 .. 40 ] characters The user's username, a unique string that identifies them in URLs. + |
display_name | string [ 1 .. 100 ] characters The user's display name. + |
bio | string [ 1 .. 1000 ] characters The user's bio/description. + |
member_title | string Optional text used for the "Members" heading on the user's profile page. + |
avatar | string A hash of the user's avatar, if set. +When editing, a base64-encoded PNG, JPEG, GIF, or WebP image file. + |
links | Array of strings Links the user has added to their profile. + |
Array of objects (Root Type for FieldEntry) The user's preferred names. + | |
Array of objects (Root Type for FieldEntry) The user's preferred pronouns. + | |
Array of objects (Field) | |
object (CustomPreferences) A user's custom preferences. + | |
list_private | boolean Whether your member list is private. + |
{- "name": "string",
- "display_name": "string",
- "bio": "string",
- "member_title": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "value": "string",
- "status": "string"
}
], - "fields": [
- {
- "name": "string",
- "entries": [
- {
- "value": "string",
- "status": "string"
}
]
}
], - "custom_preferences": {
- "property1": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}, - "property2": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}
}, - "list_private": true
}
{- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "member_title": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "value": "string",
- "status": "string"
}
], - "members": [
- {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "pronouns": "string",
- "display_text": "string",
- "status": "string"
}
]
}
], - "fields": [
- {
- "name": "string",
- "entries": [
- {
- "value": "string",
- "status": "string"
}
]
}
], - "custom_preferences": {
- "property1": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}, - "property2": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}
}, - "max_invites": 0,
- "is_admin": true,
- "list_private": true,
- "discord": "string",
- "discord_username": "string",
- "tumblr": "string",
- "tumblr_username": "string",
- "google": "string",
- "google_username": "string",
- "fediverse": "string",
- "fediverse_username": "string",
- "fediverse_instance": "string"
}
userRef required | string A user ID, username, or |
[- {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "pronouns": "string",
- "display_text": "string",
- "status": "string"
}
]
}
]
name | string The member's unique (per-user) name, used to identify them in URLs. Case insensitive. + |
display_name | string The member's display name. + |
bio | string The member's bio/description. + |
avatar | string A hash of the member's avatar, if set. +When editing, a base64-encoded PNG, JPEG, GIF, or WebP image file. + |
links | Array of strings The member's profile links. + |
Array of objects (Root Type for FieldEntry) The member's preferred names. + | |
Array of objects (PronounEntry) The member's preferred pronouns. + | |
Array of objects (Field) The member's custom label fields. + | |
object (Root Type for PartialUser) A partial user object as returned from a member endpoint. + |
{- "name": "string",
- "display_name": "string",
- "bio": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "pronouns": "string",
- "display_text": "string",
- "status": "string"
}
], - "fields": [
- {
- "name": "string",
- "entries": [
- {
- "value": "string",
- "status": "string"
}
]
}
], - "user": {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "avatar": "string",
- "custom_preferences": {
- "property1": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}, - "property2": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}
}
}
}
{- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "pronouns": "string",
- "display_text": "string",
- "status": "string"
}
], - "fields": [
- {
- "name": "string",
- "entries": [
- {
- "value": "string",
- "status": "string"
}
]
}
], - "user": {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "avatar": "string",
- "custom_preferences": {
- "property1": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}, - "property2": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}
}
}
}
{- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "pronouns": "string",
- "display_text": "string",
- "status": "string"
}
], - "fields": [
- {
- "name": "string",
- "entries": [
- {
- "value": "string",
- "status": "string"
}
]
}
], - "user": {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "avatar": "string",
- "custom_preferences": {
- "property1": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}, - "property2": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}
}
}
}
memberRef required | string The member's unique ID. + |
name | string The member's unique (per-user) name, used to identify them in URLs. Case insensitive. + |
display_name | string The member's display name. + |
bio | string The member's bio/description. + |
avatar | string A hash of the member's avatar, if set. +When editing, a base64-encoded PNG, JPEG, GIF, or WebP image file. + |
links | Array of strings The member's profile links. + |
Array of objects (Root Type for FieldEntry) The member's preferred names. + | |
Array of objects (PronounEntry) The member's preferred pronouns. + | |
Array of objects (Field) The member's custom label fields. + | |
object (Root Type for PartialUser) A partial user object as returned from a member endpoint. + |
{- "name": "string",
- "display_name": "string",
- "bio": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "pronouns": "string",
- "display_text": "string",
- "status": "string"
}
], - "fields": [
- {
- "name": "string",
- "entries": [
- {
- "value": "string",
- "status": "string"
}
]
}
], - "user": {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "avatar": "string",
- "custom_preferences": {
- "property1": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}, - "property2": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}
}
}
}
{- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "pronouns": "string",
- "display_text": "string",
- "status": "string"
}
], - "fields": [
- {
- "name": "string",
- "entries": [
- {
- "value": "string",
- "status": "string"
}
]
}
], - "user": {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "avatar": "string",
- "custom_preferences": {
- "property1": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}, - "property2": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}
}
}
}
userRef required | string A user ID, username, or |
memberRef required | string A member ID or name. + |
{- "id": "string",
- "name": "string",
- "display_name": "string",
- "bio": "string",
- "avatar": "string",
- "links": [
- "string"
], - "names": [
- {
- "value": "string",
- "status": "string"
}
], - "pronouns": [
- {
- "pronouns": "string",
- "display_text": "string",
- "status": "string"
}
], - "fields": [
- {
- "name": "string",
- "entries": [
- {
- "value": "string",
- "status": "string"
}
]
}
], - "user": {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "avatar": "string",
- "custom_preferences": {
- "property1": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}, - "property2": {
- "icon": "string",
- "tooltip": "string",
- "size": "large",
- "muted": true,
- "favourite": true
}
}
}
}
{- "git_commit": "130a199",
- "users": {
- "total": 3985,
- "active_month": 3985,
- "active_week": 1327,
- "active_day": 276
}, - "members": 11462,
- "require_invite": false
}
+
+
An internal error has occurred. Don't worry, it's (probably) not your fault.
++ If this is the first time this is happening, try reloading the page. Otherwise, check the + status page for updates. +
+
+ Status: %sveltekit.status%
+ Error message: %sveltekit.error.message%
+
+
+ {member.display_name ?? member.name}
+ {#if member.unlisted === true}
+
+ {pronouns}
+ {/if}
+
+ The page you were looking for was not found. If you're sure the page exists, check for any typos + in the address. +
+{:else if $page.status === 429} +You've exceeded a rate limit, please try again later.
+{:else if $page.status === 500} +An internal error occurred. Please try again later.
++ If this error keeps happening, please file a bug report with an explanation of what you did to cause the error. +
+{/if} + +Error message: {$page.error?.message}
Create and share all your pronouns
+ ++ {#if $userStore} + + {:else} + + {/if} +
++ Everybody uses pronouns to refer to others. Whether it be he/him, she/her, they/them, or + anything else (or nothing at all!), everybody has preferences. But how do you know which + pronouns you should use? +
++ pronouns.cc is a service where you can create and share a list of your preferred names, + pronouns, and terms to share with other people! But not just one set: you can create + multiple + lists and have all of them linked on your main profile. +
+This is useful for plural systems, people who kin, and anyone else too!
++ pronouns.cc is currently in beta. There might be issues and some + functionality is not available or unfinished. Issue reports and pull requests + in the repository are welcome! +
++ Yes! Pronouns.page, along + with pronouny.xyz, was a + direct inspiration for pronouns.cc. If those sites are working fine for you, that's great, + they're good projects! +
++ pronouns.cc is + open source, and licensed under the GNU Affero General Public License. Feel free to contribute! +
+thank you :3
+oh no :(
++ If you like pronouns.cc and want to support me financially, check out the about page! +
+The user you were looking for couldn't be found. Please check for any typos.
+{:else if $page.status === 429} +You've exceeded a rate limit, please try again later.
+{:else if $page.status === 500} +An internal error occurred. Please try again later.
++ If this error keeps happening, please file a bug report with an explanation of what you did to cause the error. +
+{/if} + +Error message: {$page.error?.message}
@{data.name}
++ + Your profile is empty! You can customize it by going to the edit profile page. (only you can see this) +
+ {:else if bio} +{@html bio}
+ {/if} +
+ You don't have any members yet.
+
+ Members are sub-profiles that can have their own avatar, names, pronouns, and preferred terms.
+
+ If you were expecting to see members here, check your
+ list of hidden members.
+ (only you can see this)
+
+
+
+ Note that we cannot take action on any reports that cannot be proven with just
+ the reported profile and any external pages linked on it.
+
{data.name} (@{data.user.name})
+ {#if profileEmpty && $userStore?.id === data.user.id} ++ + This member's profile is empty! You can customize it by going to the edit member page. (only you can see this) +
+ {:else if bio} +{@html bio}
+ {/if} +
+ @timmie@mastodon.example
, but your
+ user page is at
+ social.mastodon.example/timmie
, you should fill in
+ social.mastodon.example
.
+
+
+ Choose an authentication provider to get started. You can add more providers later. +
++ Your account is pending deletion since {DateTime.fromISO(deletedAt) + .toLocal() + .toLocaleString(DateTime.DATETIME_MED)}. +
+If you wish to cancel deletion, press the button below.
++ +
++ Alternatively, if you want your data wiped immediately, press the force delete link below. This is irreversible. +
++ +
+ {#if deleteCancelled} ++ Your account is pending deletion since {DateTime.fromISO(deletedAt) + .toLocal() + .toLocaleString(DateTime.DATETIME_MED)}. +
++ Your account was deactivated by a moderator. You cannot cancel deletion. The moderator + gave the following reason: +
++ {deleteReason} ++
+ Your account will be fully deleted 180 days after being deactivated. If you want your data wiped + immediately instead, press the force delete link below. +
++ +
+{:else} + Loading... +{/if} + +
+ If you want to delete your account, type your username ({user?.name}
) below:
+
+
+ This is irreversible! Your account cannot be recovered after you press "Force delete account".
+
+
+ +
+ {#if deleteError} +
+ Markdown is a simple way to format text, using symbols like *
, _
, and
+ `
. If you have used Discord before, formatting works the same as there, just with a
+ couple different options.
+
Type *Italic*
or _Italic_
to get Italic
Type **Bold**
or __Bold__
to get Bold
Use at least three dashes ---
on a separate line to add a horizontal rule:
Type `Inline code`
to get Inline code
Use three backticks to make a code block:
+```
print("Code here")
```
+ Type
+* List
* List
* List
+ to get
+Type
+1. List
2. List
3. List
+ to get
+
+ If you want to delete this member, type {deleteModalPronoun} name ({data.member.name}
) below:
+
+ +
+ {#if deleteError} +
+
+
That member name is not valid.
+ {/if} +
+
+ Using {charCount(bio)}/{MAX_DESCRIPTION_LENGTH} characters +
+
+
Why can't I see any flags?
++ There are thousands of pride flags, and it would be impossible to bundle all of them + by default. Many labels also have multiple different flags that are favoured by + different people. Because of this, there are no flags available by default--instead, + you can upload flags in your settings. Your main profile + and your member profiles can all have different flags. +
+ {:else} + To upload and delete flags, go to your settings. + {/if} +
+ {#if data.user.list_private}
+
+ {/if}
+ pronouns.cc/@{data.user.name}/{data.member.name}
.
+
+
+ Current short ID: {data.member.sid}
+
+
+ prns.cc
links. You can reroll one short ID every hour (shared
+ between your main profile and all members) by pressing the button above.
+
+
+
+
+
+ Using {charCount(bio)}/{MAX_DESCRIPTION_LENGTH} characters +
+
+
Why can't I see any flags?
++ There are thousands of pride flags, and it would be impossible to bundle all of them + by default. Many labels also have multiple different flags that are favoured by + different people. Because of this, there are no flags available by default--instead, + you can upload flags in your settings. Your main profile + and your member profiles can all have different flags. +
+ {:else} + To upload and delete flags, go to your settings. + {/if} +
+
+ Current short ID: {data.user.sid}
+
+
+ prns.cc
links. You can reroll one short ID every hour (shared
+ between your main profile and all members) by pressing the button above.
+
+
+ pronouns.cc/@{data.user.name}/[member-name]
.
+
+
+ +
+Here are some example sentences using {displayText} pronouns!
+ ++diff --git a/frontend/src/routes/pronouns/[...pronouns]/+page.ts b/frontend/src/routes/pronouns/[...pronouns]/+page.ts new file mode 100644 index 0000000..6ab0564 --- /dev/null +++ b/frontend/src/routes/pronouns/[...pronouns]/+page.ts @@ -0,0 +1,50 @@ +import { error } from "@sveltejs/kit"; +import type { PageLoad } from "./$types"; +import type { PronounsJson } from "$lib/api/entities"; + +import pronounsRaw from "$lib/pronouns.json"; +const pronouns = pronounsRaw as PronounsJson; + +export const load = (async ({ params }) => { + const [param, displayText] = decodeURIComponent(params.pronouns).split(","); + + const arr = param.split("/"); + if (arr.length === 0 || params.pronouns === "") { + throw error(404, "Pronouns not found"); + } + + if (arr.length === 5) { + return { + displayText, + subjective: arr[0], + objective: arr[1], + possessiveDeterminer: arr[2], + possessivePronoun: arr[3], + reflexive: arr[4], + }; + } + + if (params.pronouns in pronouns.pages) { + const entry = pronouns.pages[params.pronouns]; + return { + displayText: entry.display || "", + subjective: entry.pronouns[0], + objective: entry.pronouns[1], + possessiveDeterminer: entry.pronouns[2], + possessivePronoun: entry.pronouns[3], + reflexive: entry.pronouns[4], + }; + } else if (params.pronouns in pronouns.autocomplete) { + const entry = pronouns.autocomplete[params.pronouns]; + return { + displayText: entry.display || "", + subjective: entry.pronouns[0], + objective: entry.pronouns[1], + possessiveDeterminer: entry.pronouns[2], + possessivePronoun: entry.pronouns[3], + reflexive: entry.pronouns[4], + }; + } + + throw error(404, "Pronouns not found"); +}) satisfies PageLoad; diff --git a/frontend/src/routes/reports/+layout.svelte b/frontend/src/routes/reports/+layout.svelte new file mode 100644 index 0000000..4fa864c --- /dev/null +++ b/frontend/src/routes/reports/+layout.svelte @@ -0,0 +1 @@ +{subjective} went to the park.
+I went with {objective}.
+{subjective} brought {possessiveDeterminer} frisbee.
+At least, I think it was {possessivePronoun}.
++ {subjective} threw the frisbee to + {reflexive}. +
+
{report.reason}+
+
+ Your username must be unique, be at most 40 characters long, and only contain letters from
+ the basic English alphabet, dashes, underscores, and periods. Your username is used as part
+ of your profile link, you can set a separate display name.
+ {#if !usernameValid}
+
+
+
+ To change your avatar, go to edit profile.
+
+ If you think one of your tokens might have been compromised, you can log out on all devices + by clicking this button. +
++ +
+If you want to force log out on all devices, click the button below.
+ {#if invalidateError} +ID | +{data.user.id} |
+
---|---|
Account created at | +{DateTime.fromISO(data.user.created_at) + .toLocal() + .toLocaleString(DateTime.DATETIME_MED)} | +
Members | +{data.user.members.length}/{MAX_MEMBERS} | +
Member list hidden? | +{data.user.list_private ? "Yes" : "No"} | +
Custom preferences | +{Object.keys(data.user.custom_preferences).length}/{MAX_FIELDS} | +
Invites | +{data.invites.length}/{data.user.max_invites} | +
Admin? | +Yes | +
If you want to initiate the account deletion process, click the button below:
++ +
+
+
If you want to delete your account, type your current username below:
++ +
+ {#if deleteError} +{data.user.fediverse}
).
+ {:else}
+ You do not have a linked Fediverse account.
+ {/if}
+ {data.user.discord}
).
+ {:else}
+ You do not have a linked Discord account.
+ {/if}
+ {data.user.tumblr}
).
+ {:else}
+ You do not have a linked Tumblr account.
+ {/if}
+ {data.user.google}
).
+ {:else}
+ You do not have a linked Google account.
+ {/if}
+ + Are you sure you want to unlink your fediverse account? You will no longer be able to use + it to log in. +
+ {#if error} ++ Are you sure you want to unlink your Discord account? You will no longer be able to use it + to log in. +
+ {#if error} ++ Are you sure you want to unlink your Tumblr account? You will no longer be able to use it + to log in. +
+ {#if error} ++ Are you sure you want to unlink your Google account? You will no longer be able to use it + to log in. +
+ {#if error} +
+ You last exported your data at {createdAt.toLocaleString(DateTime.DATETIME_MED)}.
+
+ This file will be available until {createdAt
+ .plus(availableFor)
+ .toLocal()
+ .toLocaleString(DateTime.DATETIME_MED)}
+
+ Download your export file below:
+
+ +
++ You can upload pride flags to use on your profiles here. Flags you upload here will not automatically + show up on your profile. +
+ +
+
+ + +
+
+
+ + +
+
+
+ + +
++ + +
+Invites aren't required to sign up to pronouns.cc right now!
+ {:else} +Code | +Created at | +Used? | + + + {#each data.invites as invite} +
---|---|---|
{invite.code} |
+ {DateTime.fromISO(invite.created) + .toLocal() + .toLocaleString(DateTime.DATETIME_MED)} | +{invite.used ? "yes" : "no"} | +
{latestInvite?.code}
+ Created a new API token! Please save it somewhere secure, as it will only be shown once.
+{newToken}
{warning.reason}+