add bio and pronouns subpages

This commit is contained in:
sam 2023-08-07 03:10:46 +02:00
parent 93a113206f
commit 61f1464e37
No known key found for this signature in database
GPG Key ID: B4EF20DDE721CAA1
4 changed files with 133 additions and 46 deletions

View 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>

View File

@ -1,22 +1,14 @@
<script lang="ts"> <script lang="ts">
import { setContext } from "svelte"; import { setContext } from "svelte";
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import { page } from "$app/stores";
import type { LayoutData } from "./$types"; import type { LayoutData } from "./$types";
import { Button, ButtonGroup, Icon, Nav, NavItem, NavLink } from "sveltestrap"; import { Button, ButtonGroup, Icon, Nav, NavItem } from "sveltestrap";
import type { import type { MeUser, APIError } from "$lib/api/entities";
FieldEntry,
Field,
MeUser,
Pronoun,
PrideFlag,
CustomPreferences,
APIError,
} from "$lib/api/entities";
import ErrorAlert from "$lib/components/ErrorAlert.svelte"; import ErrorAlert from "$lib/components/ErrorAlert.svelte";
import { addToast, delToast } from "$lib/toast"; import { addToast, delToast } from "$lib/toast";
import { apiFetchClient } from "$lib/api/fetch"; import { apiFetchClient } from "$lib/api/fetch";
import { userStore } from "$lib/store"; import { userStore } from "$lib/store";
import ActiveLink from "$lib/components/ActiveLink.svelte";
export let data: LayoutData; export let data: LayoutData;
@ -88,41 +80,13 @@
{/if} {/if}
<Nav tabs> <Nav tabs>
<NavItem> <NavItem><ActiveLink href="/edit/profile">Names and avatar</ActiveLink></NavItem>
<NavLink href="/edit/profile" active={$page.url.pathname === "/edit/profile"} <NavItem><ActiveLink href="/edit/profile/bio">Bio</ActiveLink></NavItem>
>Names and avatar</NavLink <NavItem><ActiveLink href="/edit/profile/pronouns">Pronouns</ActiveLink></NavItem>
> <NavItem><ActiveLink href="/edit/profile/fields">Fields</ActiveLink></NavItem>
</NavItem> <NavItem><ActiveLink href="/edit/profile/flags">Flags</ActiveLink></NavItem>
<NavItem> <NavItem><ActiveLink href="/edit/profile/links">Links</ActiveLink></NavItem>
<NavLink href="/edit/profile/bio" active={$page.url.pathname === "/edit/profile/bio"} <NavItem><ActiveLink href="/edit/profile/other">Preferences & other</ActiveLink></NavItem>
>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>
</Nav> </Nav>
<div class="mt-3"> <div class="mt-3">

View 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}

View 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>