forked from mirrors/pronouns.cc
feat(frontend): show custom preferences
This commit is contained in:
parent
2c71741d7c
commit
8bda5f9860
7 changed files with 120 additions and 57 deletions
41
frontend/src/lib/api/default_preferences.ts
Normal file
41
frontend/src/lib/api/default_preferences.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { type CustomPreferences, PreferenceSize } from "./entities";
|
||||
|
||||
const defaultPreferences: CustomPreferences = {
|
||||
favourite: {
|
||||
icon: "heart-fill",
|
||||
tooltip: "Favourite",
|
||||
size: PreferenceSize.Large,
|
||||
muted: false,
|
||||
favourite: true,
|
||||
},
|
||||
okay: {
|
||||
icon: "hand-thumbs-up",
|
||||
tooltip: "Okay",
|
||||
size: PreferenceSize.Normal,
|
||||
muted: false,
|
||||
favourite: false,
|
||||
},
|
||||
jokingly: {
|
||||
icon: "emoji-laughing",
|
||||
tooltip: "Jokingly",
|
||||
size: PreferenceSize.Normal,
|
||||
muted: false,
|
||||
favourite: false,
|
||||
},
|
||||
friends_only: {
|
||||
icon: "people",
|
||||
tooltip: "Friends only",
|
||||
size: PreferenceSize.Normal,
|
||||
muted: false,
|
||||
favourite: false,
|
||||
},
|
||||
avoid: {
|
||||
icon: "people",
|
||||
tooltip: "Avoid",
|
||||
size: PreferenceSize.Small,
|
||||
muted: true,
|
||||
favourite: false,
|
||||
},
|
||||
};
|
||||
|
||||
export default defaultPreferences;
|
|
@ -16,6 +16,25 @@ export interface User {
|
|||
pronouns: Pronoun[];
|
||||
members: PartialMember[];
|
||||
fields: Field[];
|
||||
custom_preferences: CustomPreferences;
|
||||
}
|
||||
|
||||
export interface CustomPreferences {
|
||||
[key: string]: CustomPreference;
|
||||
}
|
||||
|
||||
export interface CustomPreference {
|
||||
icon: string;
|
||||
tooltip: string;
|
||||
size: PreferenceSize;
|
||||
muted: boolean;
|
||||
favourite: boolean;
|
||||
}
|
||||
|
||||
export enum PreferenceSize {
|
||||
Large = "large",
|
||||
Normal = "normal",
|
||||
Small = "small",
|
||||
}
|
||||
|
||||
export interface MeUser extends User {
|
||||
|
@ -80,6 +99,7 @@ export interface MemberPartialUser {
|
|||
name: string;
|
||||
display_name: string | null;
|
||||
avatar: string | null;
|
||||
custom_preferences: CustomPreferences;
|
||||
}
|
||||
|
||||
export interface Invite {
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
<script lang="ts">
|
||||
import type { Field } from "$lib/api/entities";
|
||||
import type { CustomPreferences, Field } from "$lib/api/entities";
|
||||
|
||||
import StatusLine from "./StatusLine.svelte";
|
||||
|
||||
export let field: Field;
|
||||
export let preferences: CustomPreferences;
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<h3>{field.name}</h3>
|
||||
<ul class="list-unstyled fs-5">
|
||||
{#each field.entries as entry}
|
||||
<li><StatusLine status={entry.status}>{entry.value}</StatusLine></li>
|
||||
<li><StatusLine {preferences} status={entry.status}>{entry.value}</StatusLine></li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -1,53 +1,24 @@
|
|||
<script lang="ts">
|
||||
import { Icon, Tooltip } from "sveltestrap";
|
||||
|
||||
import { WordStatus } from "$lib/api/entities";
|
||||
import type { CustomPreference, CustomPreferences } from "$lib/api/entities";
|
||||
import defaultPreferences from "$lib/api/default_preferences";
|
||||
|
||||
export let status: WordStatus;
|
||||
export let preferences: CustomPreferences;
|
||||
export let status: string;
|
||||
export let className: string | null = null;
|
||||
|
||||
const iconFor = (wordStatus: WordStatus) => {
|
||||
switch (wordStatus) {
|
||||
case WordStatus.Favourite:
|
||||
return "heart-fill";
|
||||
case WordStatus.Okay:
|
||||
return "hand-thumbs-up";
|
||||
case WordStatus.Jokingly:
|
||||
return "emoji-laughing";
|
||||
case WordStatus.FriendsOnly:
|
||||
return "people";
|
||||
case WordStatus.Avoid:
|
||||
return "hand-thumbs-down";
|
||||
default:
|
||||
return "hand-thumbs-up";
|
||||
}
|
||||
};
|
||||
let mergedPreferences: CustomPreferences;
|
||||
$: mergedPreferences = Object.assign(defaultPreferences, preferences);
|
||||
|
||||
const textFor = (wordStatus: WordStatus) => {
|
||||
switch (wordStatus) {
|
||||
case WordStatus.Favourite:
|
||||
return "Favourite";
|
||||
case WordStatus.Okay:
|
||||
return "Okay";
|
||||
case WordStatus.Jokingly:
|
||||
return "Jokingly";
|
||||
case WordStatus.FriendsOnly:
|
||||
return "Friends only";
|
||||
case WordStatus.Avoid:
|
||||
return "Avoid";
|
||||
default:
|
||||
return "Okay";
|
||||
}
|
||||
};
|
||||
|
||||
let statusIcon: string;
|
||||
$: statusIcon = iconFor(status);
|
||||
|
||||
let statusText: string;
|
||||
$: statusText = textFor(status);
|
||||
let currentPreference: CustomPreference;
|
||||
$: currentPreference =
|
||||
status in mergedPreferences ? mergedPreferences[status] : defaultPreferences.okay;
|
||||
|
||||
let iconElement: HTMLElement;
|
||||
</script>
|
||||
|
||||
<span bind:this={iconElement} tabindex={0}><Icon name={statusIcon} class={className} /></span>
|
||||
<Tooltip target={iconElement} placement="top">{statusText}</Tooltip>
|
||||
<span bind:this={iconElement} tabindex={0}
|
||||
><Icon name={currentPreference.icon} class={className} /></span
|
||||
>
|
||||
<Tooltip target={iconElement} placement="top">{currentPreference.tooltip}</Tooltip>
|
||||
|
|
|
@ -1,14 +1,44 @@
|
|||
<script lang="ts">
|
||||
import { WordStatus } from "$lib/api/entities";
|
||||
import { PreferenceSize } from "$lib/api/entities";
|
||||
import StatusIcon from "$lib/components/StatusIcon.svelte";
|
||||
|
||||
export let status: WordStatus;
|
||||
import type { CustomPreference, CustomPreferences } from "$lib/api/entities";
|
||||
import defaultPreferences from "$lib/api/default_preferences";
|
||||
|
||||
export let preferences: CustomPreferences;
|
||||
export let status: string;
|
||||
|
||||
let mergedPreferences: CustomPreferences;
|
||||
$: mergedPreferences = Object.assign(defaultPreferences, preferences);
|
||||
|
||||
let currentPreference: CustomPreference;
|
||||
$: currentPreference =
|
||||
status in mergedPreferences ? mergedPreferences[status] : defaultPreferences.okay;
|
||||
|
||||
let classes: string;
|
||||
$: classes = setClasses(currentPreference);
|
||||
|
||||
const setClasses = (pref: CustomPreference) => {
|
||||
let classes = "";
|
||||
if (pref.muted) {
|
||||
classes += "text-muted ";
|
||||
}
|
||||
switch (pref.size) {
|
||||
case PreferenceSize.Large:
|
||||
classes += "fs-5";
|
||||
break;
|
||||
case PreferenceSize.Normal:
|
||||
break;
|
||||
case PreferenceSize.Small:
|
||||
classes += "fs-6";
|
||||
}
|
||||
|
||||
return classes.trim();
|
||||
};
|
||||
</script>
|
||||
|
||||
{#if status === WordStatus.Favourite}
|
||||
<strong class="fs-5"><StatusIcon {status} /> <slot /></strong>
|
||||
{:else if status === WordStatus.Avoid}
|
||||
<span class="fs-6 text-muted"><StatusIcon {status} /> <slot /></span>
|
||||
{#if currentPreference.size === PreferenceSize.Large}
|
||||
<strong class={classes}><StatusIcon {preferences} {status} /> <slot /></strong>
|
||||
{:else}
|
||||
<StatusIcon {status} /> <slot />
|
||||
<span class={classes}><StatusIcon {preferences} {status} /> <slot /></span>
|
||||
{/if}
|
||||
|
|
|
@ -146,7 +146,7 @@
|
|||
<h3>Names</h3>
|
||||
<ul class="list-unstyled fs-5">
|
||||
{#each data.names as name}
|
||||
<li><StatusLine status={name.status}>{name.value}</StatusLine></li>
|
||||
<li><StatusLine preferences={data.custom_preferences} status={name.status}>{name.value}</StatusLine></li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -156,14 +156,14 @@
|
|||
<h3>Pronouns</h3>
|
||||
<ul class="list-unstyled fs-5">
|
||||
{#each data.pronouns as pronouns}
|
||||
<li><StatusLine status={pronouns.status}><PronounLink {pronouns} /></StatusLine></li>
|
||||
<li><StatusLine preferences={data.custom_preferences} status={pronouns.status}><PronounLink {pronouns} /></StatusLine></li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
{#each data.fields as field}
|
||||
<div class="col">
|
||||
<FieldCard {field} />
|
||||
<FieldCard preferences={data.custom_preferences} {field} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
<h3>Names</h3>
|
||||
<ul class="list-unstyled fs-5">
|
||||
{#each data.names as name}
|
||||
<li><StatusLine status={name.status}>{name.value}</StatusLine></li>
|
||||
<li><StatusLine preferences={data.user.custom_preferences} status={name.status}>{name.value}</StatusLine></li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -91,14 +91,14 @@
|
|||
<h3>Pronouns</h3>
|
||||
<ul class="list-unstyled fs-5">
|
||||
{#each data.pronouns as pronouns}
|
||||
<li><StatusLine status={pronouns.status}><PronounLink {pronouns} /></StatusLine></li>
|
||||
<li><StatusLine preferences={data.user.custom_preferences} status={pronouns.status}><PronounLink {pronouns} /></StatusLine></li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
{#each data.fields as field}
|
||||
<div class="col">
|
||||
<FieldCard {field} />
|
||||
<FieldCard preferences={data.user.custom_preferences} {field} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue