fix(ui): hide 'Recently Added' & 'Recent Requests' sliders when empty (#2190)
* fix(ui): hide 'Recently Added' & 'Recent Requests' sliders when empty * fix(ui): hide 'errored' sliders too * fix: type import * fix: remove unneeded React import * fix: missing TmdbTitleCard props * refactor: remove isEmpty param for never-empty sliders * fix: display empty watchlist message if autorequest enabled * fix: pr suggestion * fix(lang): remove no-longer-needed string
This commit is contained in:
@@ -20,12 +20,11 @@ import type { TvDetails } from '@server/models/Tv';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { defineMessages, FormattedNumber, useIntl } from 'react-intl';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
recentrequests: 'Recent Requests',
|
||||
norequests: 'No requests.',
|
||||
limit: '{remaining} of {limit}',
|
||||
requestsperdays: '{limit} remaining',
|
||||
unlimited: 'Unlimited',
|
||||
@@ -35,6 +34,8 @@ const messages = defineMessages({
|
||||
seriesrequest: 'Series Requests',
|
||||
recentlywatched: 'Recently Watched',
|
||||
plexwatchlist: 'Plex Watchlist',
|
||||
emptywatchlist:
|
||||
'Media added to your <PlexWatchlistSupportLink>Plex Watchlist</PlexWatchlistSupportLink> will appear here.',
|
||||
});
|
||||
|
||||
type MediaTitle = MovieDetails | TvDetails;
|
||||
@@ -70,22 +71,24 @@ const UserProfile = () => {
|
||||
? `/api/v1/user/${user.id}/quota`
|
||||
: null
|
||||
);
|
||||
const { data: watchData } = useSWR<UserWatchDataResponse>(
|
||||
user?.userType === UserType.PLEX &&
|
||||
(user.id === currentUser?.id || currentHasPermission(Permission.ADMIN))
|
||||
? `/api/v1/user/${user.id}/watch_data`
|
||||
: null
|
||||
);
|
||||
const { data: watchData, error: watchDataError } =
|
||||
useSWR<UserWatchDataResponse>(
|
||||
user?.userType === UserType.PLEX &&
|
||||
(user.id === currentUser?.id || currentHasPermission(Permission.ADMIN))
|
||||
? `/api/v1/user/${user.id}/watch_data`
|
||||
: null
|
||||
);
|
||||
const { data: watchlistItems, error: watchlistError } =
|
||||
useSWR<WatchlistResponse>(
|
||||
user?.id === currentUser?.id ||
|
||||
currentHasPermission(
|
||||
[Permission.MANAGE_REQUESTS, Permission.WATCHLIST_VIEW],
|
||||
{
|
||||
type: 'or',
|
||||
}
|
||||
)
|
||||
? `/api/v1/user/${user?.id}/watchlist`
|
||||
user?.userType === UserType.PLEX &&
|
||||
(user.id === currentUser?.id ||
|
||||
currentHasPermission(
|
||||
[Permission.MANAGE_REQUESTS, Permission.WATCHLIST_VIEW],
|
||||
{
|
||||
type: 'or',
|
||||
}
|
||||
))
|
||||
? `/api/v1/user/${user.id}/watchlist`
|
||||
: null,
|
||||
{
|
||||
revalidateOnMount: true,
|
||||
@@ -146,7 +149,15 @@ const UserProfile = () => {
|
||||
{intl.formatMessage(messages.totalrequests)}
|
||||
</dt>
|
||||
<dd className="mt-1 text-3xl font-semibold text-white">
|
||||
<FormattedNumber value={user.requestCount} />
|
||||
<Link
|
||||
href={
|
||||
user.id === currentUser?.id
|
||||
? '/profile/requests?filter=all'
|
||||
: `/users/${user?.id}/requests?filter=all`
|
||||
}
|
||||
>
|
||||
<a>{intl.formatNumber(user.requestCount)}</a>
|
||||
</Link>
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
@@ -266,40 +277,49 @@ const UserProfile = () => {
|
||||
currentHasPermission(
|
||||
[Permission.MANAGE_REQUESTS, Permission.REQUEST_VIEW],
|
||||
{ type: 'or' }
|
||||
)) && (
|
||||
<>
|
||||
<div className="slider-header">
|
||||
<Link href={`/users/${user?.id}/requests?filter=all`}>
|
||||
<a className="slider-title">
|
||||
<span>{intl.formatMessage(messages.recentrequests)}</span>
|
||||
<ArrowCircleRightIcon />
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<Slider
|
||||
sliderKey="requests"
|
||||
isLoading={!requests && !requestError}
|
||||
isEmpty={
|
||||
!!requests && !requestError && requests.results.length === 0
|
||||
}
|
||||
items={(requests?.results ?? []).map((request) => (
|
||||
<RequestCard
|
||||
key={`request-slider-item-${request.id}`}
|
||||
request={request}
|
||||
onTitleData={updateAvailableTitles}
|
||||
/>
|
||||
))}
|
||||
placeholder={<RequestCard.Placeholder />}
|
||||
emptyMessage={intl.formatMessage(messages.norequests)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{(user.id === currentUser?.id ||
|
||||
currentHasPermission(
|
||||
[Permission.MANAGE_REQUESTS, Permission.WATCHLIST_VIEW],
|
||||
{ type: 'or' }
|
||||
)) &&
|
||||
(!watchlistItems || !!watchlistItems.results.length) &&
|
||||
(!requests || !!requests.results.length) &&
|
||||
!requestError && (
|
||||
<>
|
||||
<div className="slider-header">
|
||||
<Link
|
||||
href={
|
||||
user.id === currentUser?.id
|
||||
? '/profile/requests?filter=all'
|
||||
: `/users/${user?.id}/requests?filter=all`
|
||||
}
|
||||
>
|
||||
<a className="slider-title">
|
||||
<span>{intl.formatMessage(messages.recentrequests)}</span>
|
||||
<ArrowCircleRightIcon />
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<Slider
|
||||
sliderKey="requests"
|
||||
isLoading={!requests}
|
||||
items={(requests?.results ?? []).map((request) => (
|
||||
<RequestCard
|
||||
key={`request-slider-item-${request.id}`}
|
||||
request={request}
|
||||
onTitleData={updateAvailableTitles}
|
||||
/>
|
||||
))}
|
||||
placeholder={<RequestCard.Placeholder />}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{user.userType === UserType.PLEX &&
|
||||
(user.id === currentUser?.id ||
|
||||
currentHasPermission(
|
||||
[Permission.MANAGE_REQUESTS, Permission.WATCHLIST_VIEW],
|
||||
{ type: 'or' }
|
||||
)) &&
|
||||
(!watchlistItems ||
|
||||
!!watchlistItems.results.length ||
|
||||
(user.id === currentUser?.id &&
|
||||
(user.settings?.watchlistSyncMovies ||
|
||||
user.settings?.watchlistSyncTv))) &&
|
||||
!watchlistError && (
|
||||
<>
|
||||
<div className="slider-header">
|
||||
@@ -318,7 +338,20 @@ const UserProfile = () => {
|
||||
</div>
|
||||
<Slider
|
||||
sliderKey="watchlist"
|
||||
isLoading={!watchlistItems && !watchlistError}
|
||||
isLoading={!watchlistItems}
|
||||
isEmpty={!!watchlistItems && watchlistItems.results.length === 0}
|
||||
emptyMessage={intl.formatMessage(messages.emptywatchlist, {
|
||||
PlexWatchlistSupportLink: (msg: React.ReactNode) => (
|
||||
<a
|
||||
href="https://support.plex.tv/articles/universal-watchlist/"
|
||||
className="text-white transition duration-300 hover:underline"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{msg}
|
||||
</a>
|
||||
),
|
||||
})}
|
||||
items={watchlistItems?.results.map((item) => (
|
||||
<TmdbTitleCard
|
||||
id={item.tmdbId}
|
||||
@@ -330,9 +363,11 @@ const UserProfile = () => {
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{(user.id === currentUser?.id ||
|
||||
currentHasPermission(Permission.ADMIN)) &&
|
||||
!!watchData?.recentlyWatched.length && (
|
||||
{user.userType === UserType.PLEX &&
|
||||
(user.id === currentUser?.id ||
|
||||
currentHasPermission(Permission.ADMIN)) &&
|
||||
(!watchData || !!watchData.recentlyWatched.length) &&
|
||||
!watchDataError && (
|
||||
<>
|
||||
<div className="slider-header">
|
||||
<div className="slider-title">
|
||||
@@ -342,8 +377,7 @@ const UserProfile = () => {
|
||||
<Slider
|
||||
sliderKey="media"
|
||||
isLoading={!watchData}
|
||||
isEmpty={!watchData?.recentlyWatched.length}
|
||||
items={watchData.recentlyWatched.map((item) => (
|
||||
items={watchData?.recentlyWatched.map((item) => (
|
||||
<TmdbTitleCard
|
||||
key={`media-slider-item-${item.id}`}
|
||||
id={item.id}
|
||||
|
||||
Reference in New Issue
Block a user