forked from mirrors/pronouns.cc
feat: add admin badge on profiles
This commit is contained in:
parent
a6526b7f00
commit
fad5bd5e4a
6 changed files with 58 additions and 2 deletions
|
@ -113,6 +113,12 @@ func (u User) NumProviders() (numProviders int) {
|
||||||
return numProviders
|
return numProviders
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Badge int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
BadgeAdmin Badge = 1 << 0
|
||||||
|
)
|
||||||
|
|
||||||
// usernames must match this regex
|
// usernames must match this regex
|
||||||
var usernameRegex = regexp.MustCompile(`^[\w-.]{2,40}$`)
|
var usernameRegex = regexp.MustCompile(`^[\w-.]{2,40}$`)
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ type GetUserResponse struct {
|
||||||
Fields []db.Field `json:"fields"`
|
Fields []db.Field `json:"fields"`
|
||||||
CustomPreferences db.CustomPreferences `json:"custom_preferences"`
|
CustomPreferences db.CustomPreferences `json:"custom_preferences"`
|
||||||
Flags []db.UserFlag `json:"flags"`
|
Flags []db.UserFlag `json:"flags"`
|
||||||
|
Badges db.Badge `json:"badges"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetMeResponse struct {
|
type GetMeResponse struct {
|
||||||
|
@ -82,6 +83,10 @@ func dbUserToResponse(u db.User, fields []db.Field, members []db.Member, flags [
|
||||||
Flags: flags,
|
Flags: flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if u.IsAdmin {
|
||||||
|
resp.Badges |= db.BadgeAdmin
|
||||||
|
}
|
||||||
|
|
||||||
resp.Members = make([]PartialMember, len(members))
|
resp.Members = make([]PartialMember, len(members))
|
||||||
for i := range members {
|
for i := range members {
|
||||||
resp.Members[i] = PartialMember{
|
resp.Members[i] = PartialMember{
|
||||||
|
|
|
@ -13,6 +13,7 @@ export interface User {
|
||||||
avatar: string | null;
|
avatar: string | null;
|
||||||
links: string[];
|
links: string[];
|
||||||
member_title: string | null;
|
member_title: string | null;
|
||||||
|
badges: number;
|
||||||
|
|
||||||
names: FieldEntry[];
|
names: FieldEntry[];
|
||||||
pronouns: Pronoun[];
|
pronouns: Pronoun[];
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
|
Badge,
|
||||||
Button,
|
Button,
|
||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
Icon,
|
Icon,
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
import { addToast } from "$lib/toast";
|
import { addToast } from "$lib/toast";
|
||||||
import ProfileFlag from "./ProfileFlag.svelte";
|
import ProfileFlag from "./ProfileFlag.svelte";
|
||||||
import IconButton from "$lib/components/IconButton.svelte";
|
import IconButton from "$lib/components/IconButton.svelte";
|
||||||
|
import Badges from "./badges/Badges.svelte";
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
||||||
|
@ -160,11 +162,11 @@
|
||||||
<div class="col-md">
|
<div class="col-md">
|
||||||
{#if data.display_name}
|
{#if data.display_name}
|
||||||
<div>
|
<div>
|
||||||
<h2>{data.display_name}</h2>
|
<h2>{data.display_name} <Badges userBadges={data.badges} /></h2>
|
||||||
<p class="fs-5 text-body-secondary">@{data.name}</p>
|
<p class="fs-5 text-body-secondary">@{data.name}</p>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<h2>@{data.name}</h2>
|
<h2>@{data.name} <Badges userBadges={data.badges} /></h2>
|
||||||
{/if}
|
{/if}
|
||||||
{#if profileEmpty && $userStore?.id === data.id}
|
{#if profileEmpty && $userStore?.id === data.id}
|
||||||
<hr />
|
<hr />
|
||||||
|
|
22
frontend/src/routes/@[username]/badges/Admin.svelte
Normal file
22
frontend/src/routes/@[username]/badges/Admin.svelte
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { Tooltip } from "sveltestrap";
|
||||||
|
|
||||||
|
let icon: HTMLElement;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Tooltip target={icon} placement="top">This user is an admin</Tooltip>
|
||||||
|
|
||||||
|
<div class="profile-badge" bind:this={icon}>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="1 1 15.767 14.761"
|
||||||
|
><path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M3.829.497A2.823 2.823 0 0 0 1 3.326v10.11a2.822 2.822 0 0 0 2.829 2.828h10.11a2.822 2.822 0 0 0 2.829-2.828V3.326a2.823 2.823 0 0 0-2.83-2.83zm6.103 2.427a.33.33 0 0 1 .316.233l1.099 3.603 2.943 1.09a.33.33 0 0 1 0 .62l-2.942 1.088-1.099 3.712a.33.33 0 0 1-.635 0L8.515 9.558 5.573 8.47a.33.33 0 0 1 0-.62l2.943-1.09 1.1-3.601a.33.33 0 0 1 .316-.234zm-5.073.111a.33.33 0 0 1 .31.216l.29.782.782.29a.331.331 0 0 1 0 .62l-.783.29-.289.782a.33.33 0 0 1-.62 0l-.29-.782-.782-.29a.33.33 0 0 1 0-.62l.782-.29.29-.782a.33.33 0 0 1 .31-.216zM6.294 9.87c.149 0 .28.1.319.244l.297 1.091.765.283a.33.33 0 0 1 0 .62l-.76.283-.3 1.197a.331.331 0 0 1-.642 0l-.3-1.197-.762-.282a.33.33 0 0 1 0-.62l.766-.284.297-1.091a.33.33 0 0 1 .32-.244z"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.profile-badge {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
</style>
|
20
frontend/src/routes/@[username]/badges/Badges.svelte
Normal file
20
frontend/src/routes/@[username]/badges/Badges.svelte
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import Admin from "./Admin.svelte";
|
||||||
|
|
||||||
|
export let userBadges: number;
|
||||||
|
|
||||||
|
let isAdmin: boolean;
|
||||||
|
$: isAdmin = (userBadges & (1 << 0)) === 1 << 0;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="profile-badges">
|
||||||
|
{#if isAdmin}
|
||||||
|
<Admin />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.profile-badges {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in a new issue