feat: follow requests

This commit is contained in:
mae taylor 2025-07-14 18:45:38 +01:00
parent 563541d0e6
commit e3586f4eec
Signed by: mae
GPG key ID: 3C80D76BA7A3B9BD
4 changed files with 179 additions and 3 deletions

View file

@ -1,10 +1,144 @@
<script>
import { followRequests } from '$lib/followRequests.js';
import PageHeader from '../../lib/ui/core/PageHeader.svelte';
import Lang from '$lib/lang';
import {server} from '$lib/client/server';
import {app} from '$lib/client/app';
import Button from '../../lib/ui/Button.svelte';
import * as api from '$lib/api'
import TickIcon from '../../img/icons/tick.svg'
import CrossIcon from '../../img/icons/cross.svg'
import { get } from 'svelte/store';
const lang = Lang('en_GB');
async function actionRequest(account_id, approved) {
// remove item from array first - this updates the ui and
// makes the interaction more seamless
$followRequests.splice(
$followRequests.indexOf(
$followRequests.find(r => r.id)
),
1
);
// hack: force the state to update now that we just spliced the array
$followRequests = $followRequests
if(approved) {
await api.acceptFollowRequest(
get(server).host,
get(app).token,
account_id
)
} else {
await api.rejectFollowRequest(
get(server).host,
get(app).token,
account_id
)
}
}
// aliases
const acceptRequest = (id) => actionRequest(id, true);
const denyRequest = (id) => actionRequest(id, false);
</script>
<div>
<PageHeader title={lang.string('navigation.follow_requests')}/>
</div>
{#if $followRequests.length < 1}
<p class="request-zero">{lang.string('follow_requests.none')}</p>
{/if}
<style></style>
{#each $followRequests as req}
<div class="request">
<a href="/{$server.host}/@{req.fqn}" class="request-avatar-container" on:mouseup|stopPropagation>
<img src={req.avatar_url} alt="" width="48" height="48" class="post-avatar" loading="lazy" decoding="async">
</a>
<div class="info">
<div class="request-user-info">
<a href="/{$server.host}/@{req.fqn}" class="name">{@html req.rich_name}</a>
<span class="username">{req.mention}</span>
</div>
</div>
<div class="request-options">
<Button filled title="Yes" on:click={() => acceptRequest(req.id)}>
<TickIcon width="24px"/>
</Button>
<Button title="No" on:click={() => denyRequest(req.id)}>
<CrossIcon width="24px"/>
</Button>
</div>
</div>
{/each}
<style>
.request {
width: 100%;
display: flex;
flex-direction: row;
background: var(--bg-900);
padding: .5rem;
border-radius: 8px;
}
.request a,
.request a:visited {
color: inherit;
text-decoration: none;
}
.request a:hover {
text-decoration: underline;
}
.request-avatar-container {
margin-right: 12px;
display: flex;
}
.post-avatar {
border-radius: 8px;
}
.info {
display: flex;
flex-grow: 1;
flex-direction: row;
}
.request-user-info {
margin-top: -2px;
display: flex;
flex-direction: column;
justify-content: center;
}
.request-user-info a {
display: block;
}
.request-user-info .username {
opacity: .8;
font-size: .9em;
}
.request-options {
display: flex;
gap: 8px;
}
.request-options :global(button) {
width: fit-content;
height: 100%;
}
.request-zero {
opacity: 0.8;
font-size: 0.95rem;
text-align: center;
}
</style>