/**
* Renders the Follow buttons of a user's profile and of a playlist's page.
* Both go through `FollowContext`, which follows at once and rolls back when
* the request fails; the button then says so beside it.
*
* @module
*/
import { useState } from "react";
import { t } from "@lingui/core/macro";
import { Trans } from "@lingui/react/macro";
import { useAuth } from "../../hooks/auth/useAuth.ts";
import { useFollows } from "../../hooks/social/useFollows.ts";
/** Passed to {@link FollowUserButton} by the `UserPublicProfile` page. */
export interface FollowUserButtonProps {
targetUserId: string;
/** Names the user in the button's accessible label. */
targetUsername: string;
}
/** Passed to {@link FollowPlaylistButton} by `PlaylistHeader`. */
export interface FollowPlaylistButtonProps {
targetPlaylistId: string;
/** Hides the button, since only a public playlist can be followed. */
isPublic: boolean;
}
/**
* Renders the button that follows or unfollows a user. It renders nothing for
* a visitor or on the user's own profile, and is disabled until the follows
* have loaded.
*/
export function FollowUserButton(
{ targetUserId, targetUsername }: FollowUserButtonProps,
): React.JSX.Element | null {
const { user } = useAuth();
const { followedUserIds, followUser, unfollowUser, isLoaded } = useFollows();
const [failed, setFailed] = useState(false);
if (!user || user.id === targetUserId) return null;
const isFollowing = followedUserIds.has(targetUserId);
return (
<>
{failed && }
>
);
}
/**
* Renders the button that follows or unfollows a playlist. It renders nothing
* for a visitor or a private playlist, and is disabled until the follows have
* loaded. Unlike {@link FollowUserButton}, it shows on the user's own
* playlists too.
*/
export function FollowPlaylistButton(
{ targetPlaylistId, isPublic }: FollowPlaylistButtonProps,
): React.JSX.Element | null {
const { user } = useAuth();
const { followedPlaylistIds, followPlaylist, unfollowPlaylist, isLoaded } =
useFollows();
const [failed, setFailed] = useState(false);
if (!user || !isPublic) return null;
const isFollowing = followedPlaylistIds.has(targetPlaylistId);
return (
<>
{failed && }
>
);
}
function FollowError(): React.JSX.Element {
return (
Couldn't update. Try again.
);
}