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": { | ||||
|         "timeline": "Timeline", | ||||
|         "notifications": "Notifications", | ||||
|         "follow_requests": "Follow requests", | ||||
|         "explore": "Explore", | ||||
|         "lists": "Lists", | ||||
| 
 | ||||
|  |  | |||
|  | @ -176,6 +176,32 @@ export async function getNotifications(host, token, min_id, max_id, limit, types | |||
|     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} | ||||
|  * @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 { goto } from '$app/navigation'; | ||||
|     import { page } from '$app/stores'; | ||||
|     import { createEventDispatcher } from 'svelte'; | ||||
|     import { createEventDispatcher, onMount } from 'svelte'; | ||||
|     import { unread_notif_count } from '$lib/notifications.js'; | ||||
|     import { fetchFollowRequests, followRequests } from '$lib/followRequests.js' | ||||
|     import Lang from '$lib/lang'; | ||||
| 
 | ||||
|     import Logo from '$lib/../img/campfire-logo.svg'; | ||||
|  | @ -24,6 +25,7 @@ | |||
|     import InfoIcon from '../../img/icons/info.svg'; | ||||
|     import SettingsIcon from '../../img/icons/settings.svg'; | ||||
|     import LogoutIcon from '../../img/icons/logout.svg'; | ||||
|     import FollowersIcon from '../../img/icons/followers.svg'; | ||||
| 
 | ||||
|     const VERSION = APP_VERSION; | ||||
|     const lang = Lang('en_GB'); | ||||
|  | @ -40,7 +42,7 @@ | |||
|         goto(`/${$server.host}/${$account.username}`); | ||||
|     } | ||||
| 
 | ||||
|     async function log_out() { | ||||
|     async function logOut() { | ||||
|         if (!confirm("This will log you out. Are you sure?")) return; | ||||
|          | ||||
|         const res = await api.revokeToken( | ||||
|  | @ -59,6 +61,10 @@ | |||
| 
 | ||||
|         goto("/"); | ||||
|     } | ||||
| 
 | ||||
|     onMount(async () => { | ||||
|         await fetchFollowRequests(true) | ||||
|     }) | ||||
| </script> | ||||
| 
 | ||||
| <div id="navigation"> | ||||
|  | @ -91,6 +97,19 @@ | |||
|                 </span> | ||||
|             {/if} | ||||
|         </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> | ||||
|             <svelte:fragment slot="icon"> | ||||
|                 <ExploreIcon height="auto"/> | ||||
|  | @ -142,7 +161,7 @@ | |||
|                     <SettingsIcon/> | ||||
|                 </svelte:fragment> | ||||
|             </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"> | ||||
|                     <LogoutIcon/> | ||||
|                 </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