Add follow button next to each user in search results
Extract FollowButton and shared follow/unfollow actions, reused by the user profile page.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type { PageServerLoad, Actions } from './$types';
|
||||
import { createApiClient, unwrapOrError } from '$lib/server/api';
|
||||
import { addAlbumToPlaylistAction, addTrackAction } from '$lib/server/playlistActions';
|
||||
import { followUserAction, unfollowUserAction } from '$lib/server/followActions';
|
||||
import {
|
||||
EXPLORE_ALBUMS_PAGE_SIZE,
|
||||
EXPLORE_PAGE_SIZE as PAGE_SIZE,
|
||||
@@ -45,16 +46,38 @@ export const load: PageServerLoad = async ({ url, locals, fetch }) => {
|
||||
|
||||
const tracks = unwrapOrError(tracksRes, 'No se pudieron cargar las canciones.');
|
||||
|
||||
const userItems = usersRes?.data?.items ?? [];
|
||||
const followedIds = user
|
||||
? await Promise.all(
|
||||
userItems
|
||||
.filter((u) => u.id !== user.sub)
|
||||
.map((u) =>
|
||||
api
|
||||
.GET('/users/{id}/is-following', { params: { path: { id: u.id } } })
|
||||
.then((res) => (res.data ? u.id : null))
|
||||
.catch(() => null)
|
||||
)
|
||||
)
|
||||
: [];
|
||||
const followed = new Set(followedIds);
|
||||
|
||||
return {
|
||||
query,
|
||||
tracks,
|
||||
albums: (albumsRes?.data?.items ?? []).map((item) => item.album),
|
||||
users: usersRes?.data?.items ?? [],
|
||||
users: userItems.map((u) => ({
|
||||
...u,
|
||||
isSelf: user?.sub === u.id,
|
||||
isFollowing: followed.has(u.id)
|
||||
})),
|
||||
canFollow: !!user,
|
||||
playlists: playlistsRes?.data?.items ?? []
|
||||
};
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
addTrack: addTrackAction,
|
||||
addAlbumToPlaylist: addAlbumToPlaylistAction
|
||||
addAlbumToPlaylist: addAlbumToPlaylistAction,
|
||||
follow: followUserAction,
|
||||
unfollow: unfollowUserAction
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import InfiniteScroll from '$lib/components/ui/primitives/InfiniteScroll.svelte';
|
||||
import Artwork from '$lib/components/ui/media/Artwork.svelte';
|
||||
import Avatar from '$lib/components/ui/media/Avatar.svelte';
|
||||
import FollowButton from '$lib/components/ui/media/FollowButton.svelte';
|
||||
import PlayButton from '$lib/components/ui/media/PlayButton.svelte';
|
||||
import EqBars from '$lib/components/ui/media/EqBars.svelte';
|
||||
import ListRow from '$lib/components/ui/media/ListRow.svelte';
|
||||
@@ -400,12 +401,15 @@
|
||||
<SectionHeading title="Usuarios" count={counts.Usuarios} />
|
||||
<ul class="flex flex-col gap-1">
|
||||
{#each capped(sfilter, users) as u (u.id)}
|
||||
<li>
|
||||
<ListRow title={u.name} href="/user/{u.id}" size="lg">
|
||||
<li class="flex items-center gap-3">
|
||||
<ListRow title={u.name} href="/user/{u.id}" size="lg" class="min-w-0 flex-1">
|
||||
{#snippet art()}
|
||||
<Avatar name={u.name} src={u.profilePictureUrl} size="md" />
|
||||
{/snippet}
|
||||
</ListRow>
|
||||
{#if data.canFollow && !u.isSelf}
|
||||
<FollowButton following={u.isFollowing} userId={u.id} class="shrink-0" />
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user