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