forked from blisstown/campfire
feat: follow requests in sidebar
This commit is contained in:
parent
0dd903a4eb
commit
6f446fd871
6 changed files with 117 additions and 3 deletions
|
@ -23,6 +23,7 @@
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"timeline": "Timeline",
|
"timeline": "Timeline",
|
||||||
"notifications": "Notifications",
|
"notifications": "Notifications",
|
||||||
|
"follow_requests": "Follow requests",
|
||||||
"explore": "Explore",
|
"explore": "Explore",
|
||||||
"lists": "Lists",
|
"lists": "Lists",
|
||||||
|
|
||||||
|
|
|
@ -176,6 +176,32 @@ export async function getNotifications(host, token, min_id, max_id, limit, types
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/v1/follow_requests
|
||||||
|
* @param {string} host - The domain of the target server.
|
||||||
|
* @param {string} token - The application token.
|
||||||
|
* @param {string} min_id - If provided, only shows follow requests since this ID.
|
||||||
|
* @param {string} max_id - If provided, only shows follow requests before this ID.
|
||||||
|
* @param {string} limit - The maximum number of follow requests to retrieve (default 40, max 80).
|
||||||
|
*/
|
||||||
|
export async function getFollowRequests(host, token, since_id, max_id, limit) {
|
||||||
|
let url = `https://${host}/api/v1/follow_requests`;
|
||||||
|
|
||||||
|
let params = new URLSearchParams();
|
||||||
|
if (since_id) params.append("since_id", since_id);
|
||||||
|
if (max_id) params.append("max_id", max_id);
|
||||||
|
if (limit) params.append("limit", limit);
|
||||||
|
const params_string = params.toString();
|
||||||
|
if (params_string) url += '?' + params_string;
|
||||||
|
|
||||||
|
const data = await fetch(url, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: { "Authorization": "Bearer " + token }
|
||||||
|
}).then(res => res.json());
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api/v1/timelines/{timeline}
|
* GET /api/v1/timelines/{timeline}
|
||||||
* @param {string} host - The domain of the target server.
|
* @param {string} host - The domain of the target server.
|
||||||
|
|
24
src/lib/followRequests.js
Normal file
24
src/lib/followRequests.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import { server } from './client/server.js';
|
||||||
|
import { writable } from "svelte/store";
|
||||||
|
import * as api from "./api.js";
|
||||||
|
import { app } from './client/app.js';
|
||||||
|
import { get } from 'svelte/store';
|
||||||
|
|
||||||
|
// Cache for all requests
|
||||||
|
export let followRequests = writable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all follow requests
|
||||||
|
* @param {boolean} force
|
||||||
|
*/
|
||||||
|
export async function fetchFollowRequests(force) {
|
||||||
|
// if already cached, return for now
|
||||||
|
if(!get(followRequests) && !force) return;
|
||||||
|
|
||||||
|
let newReqs = await api.getFollowRequests(
|
||||||
|
get(server).host,
|
||||||
|
get(app).token
|
||||||
|
);
|
||||||
|
|
||||||
|
followRequests.set(newReqs);
|
||||||
|
}
|
|
@ -6,8 +6,9 @@
|
||||||
import { playSound } from '$lib/sound.js';
|
import { playSound } from '$lib/sound.js';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher, onMount } from 'svelte';
|
||||||
import { unread_notif_count } from '$lib/notifications.js';
|
import { unread_notif_count } from '$lib/notifications.js';
|
||||||
|
import { fetchFollowRequests, followRequests } from '$lib/followRequests.js'
|
||||||
import Lang from '$lib/lang';
|
import Lang from '$lib/lang';
|
||||||
|
|
||||||
import Logo from '$lib/../img/campfire-logo.svg';
|
import Logo from '$lib/../img/campfire-logo.svg';
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
import InfoIcon from '../../img/icons/info.svg';
|
import InfoIcon from '../../img/icons/info.svg';
|
||||||
import SettingsIcon from '../../img/icons/settings.svg';
|
import SettingsIcon from '../../img/icons/settings.svg';
|
||||||
import LogoutIcon from '../../img/icons/logout.svg';
|
import LogoutIcon from '../../img/icons/logout.svg';
|
||||||
|
import FollowersIcon from '../../img/icons/followers.svg';
|
||||||
|
|
||||||
const VERSION = APP_VERSION;
|
const VERSION = APP_VERSION;
|
||||||
const lang = Lang('en_GB');
|
const lang = Lang('en_GB');
|
||||||
|
@ -40,7 +42,7 @@
|
||||||
goto(`/${$server.host}/${$account.username}`);
|
goto(`/${$server.host}/${$account.username}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function log_out() {
|
async function logOut() {
|
||||||
if (!confirm("This will log you out. Are you sure?")) return;
|
if (!confirm("This will log you out. Are you sure?")) return;
|
||||||
|
|
||||||
const res = await api.revokeToken(
|
const res = await api.revokeToken(
|
||||||
|
@ -59,6 +61,10 @@
|
||||||
|
|
||||||
goto("/");
|
goto("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
await fetchFollowRequests(true)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="navigation">
|
<div id="navigation">
|
||||||
|
@ -91,6 +97,19 @@
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</Button>
|
</Button>
|
||||||
|
{#if $followRequests.length > 0}
|
||||||
|
<Button label="Follow requests"
|
||||||
|
href="/follow-requests"}
|
||||||
|
active={$page.url.pathname === "/follow-requests"}>
|
||||||
|
<svelte:fragment slot="icon">
|
||||||
|
<FollowersIcon/>
|
||||||
|
</svelte:fragment>
|
||||||
|
{lang.string('navigation.follow_requests')}
|
||||||
|
<span class="notification-count">
|
||||||
|
{$followRequests.length}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
<Button label="Explore" disabled>
|
<Button label="Explore" disabled>
|
||||||
<svelte:fragment slot="icon">
|
<svelte:fragment slot="icon">
|
||||||
<ExploreIcon height="auto"/>
|
<ExploreIcon height="auto"/>
|
||||||
|
@ -142,7 +161,7 @@
|
||||||
<SettingsIcon/>
|
<SettingsIcon/>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</Button>
|
</Button>
|
||||||
<Button centered label="{lang.string('navigation.log_out')}" on:click={() => log_out()}>
|
<Button centered label="{lang.string('navigation.log_out')}" on:click={() => logOut()}>
|
||||||
<svelte:fragment slot="icon">
|
<svelte:fragment slot="icon">
|
||||||
<LogoutIcon/>
|
<LogoutIcon/>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
|
34
src/lib/ui/core/PageHeader.svelte
Normal file
34
src/lib/ui/core/PageHeader.svelte
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<script>
|
||||||
|
export let title;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1>{title}</h1>
|
||||||
|
<slot name="icon" />
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
header {
|
||||||
|
width: 100%;
|
||||||
|
height: 64px;
|
||||||
|
margin: 16px 0;
|
||||||
|
padding: 0 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
user-select: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
margin-left: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
10
src/routes/follow-requests/+page.svelte
Normal file
10
src/routes/follow-requests/+page.svelte
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<script>
|
||||||
|
import { followRequests } from '$lib/followRequests.js';
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style></style>
|
Loading…
Add table
Add a link
Reference in a new issue