forked from mirrors/pronouns.cc
add bio and pronouns subpages
This commit is contained in:
parent
93a113206f
commit
61f1464e37
4 changed files with 133 additions and 46 deletions
10
frontend/src/lib/components/ActiveLink.svelte
Normal file
10
frontend/src/lib/components/ActiveLink.svelte
Normal file
|
@ -0,0 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { NavLink } from "sveltestrap";
|
||||
import { page } from "$app/stores";
|
||||
|
||||
export let href: string;
|
||||
</script>
|
||||
|
||||
<NavLink {href} active={$page.url.pathname === href}>
|
||||
<slot />
|
||||
</NavLink>
|
|
@ -1,22 +1,14 @@
|
|||
<script lang="ts">
|
||||
import { setContext } from "svelte";
|
||||
import { writable } from "svelte/store";
|
||||
import { page } from "$app/stores";
|
||||
import type { LayoutData } from "./$types";
|
||||
import { Button, ButtonGroup, Icon, Nav, NavItem, NavLink } from "sveltestrap";
|
||||
import type {
|
||||
FieldEntry,
|
||||
Field,
|
||||
MeUser,
|
||||
Pronoun,
|
||||
PrideFlag,
|
||||
CustomPreferences,
|
||||
APIError,
|
||||
} from "$lib/api/entities";
|
||||
import { Button, ButtonGroup, Icon, Nav, NavItem } from "sveltestrap";
|
||||
import type { MeUser, APIError } from "$lib/api/entities";
|
||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||
import { addToast, delToast } from "$lib/toast";
|
||||
import { apiFetchClient } from "$lib/api/fetch";
|
||||
import { userStore } from "$lib/store";
|
||||
import ActiveLink from "$lib/components/ActiveLink.svelte";
|
||||
|
||||
export let data: LayoutData;
|
||||
|
||||
|
@ -88,41 +80,13 @@
|
|||
{/if}
|
||||
|
||||
<Nav tabs>
|
||||
<NavItem>
|
||||
<NavLink href="/edit/profile" active={$page.url.pathname === "/edit/profile"}
|
||||
>Names and avatar</NavLink
|
||||
>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink href="/edit/profile/bio" active={$page.url.pathname === "/edit/profile/bio"}
|
||||
>Bio</NavLink
|
||||
>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink href="/edit/profile/pronouns" active={$page.url.pathname === "/edit/profile/pronouns"}
|
||||
>Pronouns</NavLink
|
||||
>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink href="/edit/profile/fields" active={$page.url.pathname === "/edit/profile/fields"}
|
||||
>Fields</NavLink
|
||||
>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink href="/edit/profile/flags" active={$page.url.pathname === "/edit/profile/flags"}
|
||||
>Flags</NavLink
|
||||
>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink href="/edit/profile/links" active={$page.url.pathname === "/edit/profile/links"}
|
||||
>Links</NavLink
|
||||
>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink href="/edit/profile/other" active={$page.url.pathname === "/edit/profile/other"}
|
||||
>Preferences & other</NavLink
|
||||
>
|
||||
</NavItem>
|
||||
<NavItem><ActiveLink href="/edit/profile">Names and avatar</ActiveLink></NavItem>
|
||||
<NavItem><ActiveLink href="/edit/profile/bio">Bio</ActiveLink></NavItem>
|
||||
<NavItem><ActiveLink href="/edit/profile/pronouns">Pronouns</ActiveLink></NavItem>
|
||||
<NavItem><ActiveLink href="/edit/profile/fields">Fields</ActiveLink></NavItem>
|
||||
<NavItem><ActiveLink href="/edit/profile/flags">Flags</ActiveLink></NavItem>
|
||||
<NavItem><ActiveLink href="/edit/profile/links">Links</ActiveLink></NavItem>
|
||||
<NavItem><ActiveLink href="/edit/profile/other">Preferences & other</ActiveLink></NavItem>
|
||||
</Nav>
|
||||
|
||||
<div class="mt-3">
|
||||
|
|
29
frontend/src/routes/edit/profile/bio/+page.svelte
Normal file
29
frontend/src/routes/edit/profile/bio/+page.svelte
Normal file
|
@ -0,0 +1,29 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from "svelte";
|
||||
import type { Writable } from "svelte/store";
|
||||
import { MAX_DESCRIPTION_LENGTH, type MeUser } from "$lib/api/entities";
|
||||
import { charCount, renderMarkdown } from "$lib/utils";
|
||||
import MarkdownHelp from "../../MarkdownHelp.svelte";
|
||||
import { Card, CardBody, CardHeader } from "sveltestrap";
|
||||
|
||||
const user = getContext<Writable<MeUser>>("user");
|
||||
</script>
|
||||
|
||||
<div class="form">
|
||||
<textarea class="form-control" style="height: 200px;" bind:value={$user.bio} />
|
||||
</div>
|
||||
<p class="text-muted mt-1">
|
||||
Using {charCount($user.bio || "")}/{MAX_DESCRIPTION_LENGTH} characters
|
||||
</p>
|
||||
<p class="text-muted my-2">
|
||||
<MarkdownHelp />
|
||||
</p>
|
||||
{#if $user.bio}
|
||||
<hr />
|
||||
<Card>
|
||||
<CardHeader>Preview</CardHeader>
|
||||
<CardBody>
|
||||
{@html renderMarkdown($user.bio)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
{/if}
|
84
frontend/src/routes/edit/profile/pronouns/+page.svelte
Normal file
84
frontend/src/routes/edit/profile/pronouns/+page.svelte
Normal file
|
@ -0,0 +1,84 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from "svelte";
|
||||
import type { Writable } from "svelte/store";
|
||||
import type { MeUser } from "$lib/api/entities";
|
||||
import { Button, Icon, Popover } from "sveltestrap";
|
||||
import EditablePronouns from "../../EditablePronouns.svelte";
|
||||
import IconButton from "$lib/components/IconButton.svelte";
|
||||
import type { PageData } from "./$types";
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
const user = getContext<Writable<MeUser>>("user");
|
||||
let newPronouns = "";
|
||||
|
||||
const movePronoun = (index: number, up: boolean) => {
|
||||
if (up && index == 0) return;
|
||||
if (!up && index == $user.pronouns.length - 1) return;
|
||||
|
||||
const newIndex = up ? index - 1 : index + 1;
|
||||
|
||||
const temp = $user.pronouns[index];
|
||||
$user.pronouns[index] = $user.pronouns[newIndex];
|
||||
$user.pronouns[newIndex] = temp;
|
||||
$user.pronouns = [...$user.pronouns];
|
||||
};
|
||||
|
||||
const addPronouns = (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (newPronouns in data.pronouns) {
|
||||
const fullSet = data.pronouns[newPronouns];
|
||||
$user.pronouns = [
|
||||
...$user.pronouns,
|
||||
{
|
||||
pronouns: fullSet.pronouns.join("/"),
|
||||
display_text: fullSet.display || null,
|
||||
status: "okay",
|
||||
},
|
||||
];
|
||||
} else {
|
||||
$user.pronouns = [
|
||||
...$user.pronouns,
|
||||
{ pronouns: newPronouns, display_text: null, status: "okay" },
|
||||
];
|
||||
}
|
||||
newPronouns = "";
|
||||
};
|
||||
|
||||
const removePronoun = (index: number) => {
|
||||
$user.pronouns.splice(index, 1);
|
||||
$user.pronouns = [...$user.pronouns];
|
||||
};
|
||||
</script>
|
||||
|
||||
{#each $user.pronouns as _, index}
|
||||
<EditablePronouns
|
||||
bind:pronoun={$user.pronouns[index]}
|
||||
preferences={$user.custom_preferences}
|
||||
moveUp={() => movePronoun(index, true)}
|
||||
moveDown={() => movePronoun(index, false)}
|
||||
remove={() => removePronoun(index)}
|
||||
/>
|
||||
{/each}
|
||||
<form class="input-group m-1" on:submit={addPronouns}>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
placeholder="New pronouns"
|
||||
bind:value={newPronouns}
|
||||
required
|
||||
/>
|
||||
<IconButton
|
||||
type="submit"
|
||||
color="success"
|
||||
icon="plus"
|
||||
tooltip="Add pronouns"
|
||||
disabled={newPronouns === ""}
|
||||
/>
|
||||
<Button id="pronouns-help" color="secondary"><Icon name="question" /></Button>
|
||||
<Popover target="pronouns-help" placement="bottom">
|
||||
For common pronouns, the short form (e.g. "she/her" or "he/him") is enough; for less common
|
||||
pronouns, you will have to use all five forms (e.g. "ce/cir/cir/cirs/cirself").
|
||||
</Popover>
|
||||
</form>
|
Loading…
Reference in a new issue