@@ -3,6 +3,7 @@ import Badge from '@app/components/Common/Badge';
33import Button from '@app/components/Common/Button' ;
44import CachedImage from '@app/components/Common/CachedImage' ;
55import ConfirmButton from '@app/components/Common/ConfirmButton' ;
6+ import Tooltip from '@app/components/Common/Tooltip' ;
67import RequestModal from '@app/components/RequestModal' ;
78import StatusBadge from '@app/components/StatusBadge' ;
89import useDeepLinks from '@app/hooks/useDeepLinks' ;
@@ -14,9 +15,15 @@ import {
1415 getRequestDownloadStatus ,
1516 refreshIntervalHelper ,
1617} from '@app/utils/refreshIntervalHelper' ;
18+ import {
19+ canRetryRequest ,
20+ canSearchAnotherListing ,
21+ formatFailureReason ,
22+ } from '@app/utils/requestFailureHelpers' ;
1723import {
1824 ArrowPathIcon ,
1925 CheckIcon ,
26+ MagnifyingGlassIcon ,
2027 PencilIcon ,
2128 TrashIcon ,
2229 XMarkIcon ,
@@ -139,11 +146,19 @@ const RequestItemError = ({
139146 </ span >
140147 { requestData . status === MediaRequestStatus . DECLINED ||
141148 requestData . status === MediaRequestStatus . FAILED ? (
142- < Badge badgeType = "danger" >
143- { requestData . status === MediaRequestStatus . DECLINED
144- ? intl . formatMessage ( globalMessages . declined )
145- : intl . formatMessage ( globalMessages . failed ) }
146- </ Badge >
149+ < Tooltip
150+ content = { formatFailureReason (
151+ intl ,
152+ requestData . type ,
153+ requestData . failureReason
154+ ) }
155+ >
156+ < Badge badgeType = "danger" >
157+ { requestData . status === MediaRequestStatus . DECLINED
158+ ? intl . formatMessage ( globalMessages . declined )
159+ : intl . formatMessage ( globalMessages . failed ) }
160+ </ Badge >
161+ </ Tooltip >
147162 ) : (
148163 < StatusBadge
149164 status = {
@@ -527,12 +542,20 @@ const RequestItem = ({ request, revalidateList }: RequestItemProps) => {
527542 { intl . formatMessage ( globalMessages . declined ) }
528543 </ Badge >
529544 ) : requestData . status === MediaRequestStatus . FAILED ? (
530- < Badge
531- badgeType = "danger"
532- href = { `/${ requestData . type } /${ requestData . media . tmdbId } ?manage=1` }
545+ < Tooltip
546+ content = { formatFailureReason (
547+ intl ,
548+ requestData . type ,
549+ requestData . failureReason
550+ ) }
533551 >
534- { intl . formatMessage ( globalMessages . failed ) }
535- </ Badge >
552+ < Badge
553+ badgeType = "danger"
554+ href = { `/${ requestData . type } /${ requestData . media . tmdbId } ?manage=1` }
555+ >
556+ { intl . formatMessage ( globalMessages . failed ) }
557+ </ Badge >
558+ </ Tooltip >
536559 ) : requestData . status === MediaRequestStatus . PENDING &&
537560 requestData . media [ requestData . is4k ? 'status4k' : 'status' ] ===
538561 MediaStatus . DELETED ? (
@@ -683,22 +706,50 @@ const RequestItem = ({ request, revalidateList }: RequestItemProps) => {
683706 < div className = "z-10 mt-4 flex w-full flex-col justify-center space-y-2 pl-4 pr-4 xl:mt-0 xl:w-96 xl:items-end xl:pl-0" >
684707 { requestData . status === MediaRequestStatus . FAILED &&
685708 hasPermission ( Permission . MANAGE_REQUESTS ) && (
686- < Button
687- className = "w-full"
688- buttonType = "primary"
689- disabled = { isRetrying }
690- onClick = { ( ) => retryRequest ( ) }
709+ < Tooltip
710+ content = {
711+ canRetryRequest ( requestData . failureReason )
712+ ? undefined
713+ : intl . formatMessage ( globalMessages . retryunavailable )
714+ }
691715 >
692- < ArrowPathIcon
693- className = { isRetrying ? 'animate-spin' : '' }
694- style = { { animationDirection : 'reverse' } }
695- />
696- < span >
697- { intl . formatMessage (
698- isRetrying ? globalMessages . retrying : globalMessages . retry
699- ) }
700- </ span >
701- </ Button >
716+ < Button
717+ className = "w-full"
718+ buttonType = "primary"
719+ disabled = {
720+ isRetrying || ! canRetryRequest ( requestData . failureReason )
721+ }
722+ onClick = { ( ) => retryRequest ( ) }
723+ >
724+ < ArrowPathIcon
725+ className = { isRetrying ? 'animate-spin' : '' }
726+ style = { { animationDirection : 'reverse' } }
727+ />
728+ < span >
729+ { intl . formatMessage (
730+ isRetrying
731+ ? globalMessages . retrying
732+ : globalMessages . retry
733+ ) }
734+ </ span >
735+ </ Button >
736+ </ Tooltip >
737+ ) }
738+ { requestData . status === MediaRequestStatus . FAILED &&
739+ canSearchAnotherListing ( requestData . failureReason ) &&
740+ title && (
741+ < Link
742+ href = { `/search?query=${ encodeURIComponent (
743+ isMovie ( title ) ? title . title : title . name
744+ ) } `}
745+ passHref
746+ legacyBehavior
747+ >
748+ < Button as = "a" className = "w-full" buttonType = "default" >
749+ < MagnifyingGlassIcon />
750+ < span > { intl . formatMessage ( globalMessages . findlisting ) } </ span >
751+ </ Button >
752+ </ Link >
702753 ) }
703754 { requestData . status !== MediaRequestStatus . PENDING &&
704755 hasPermission ( Permission . MANAGE_REQUESTS ) && (
0 commit comments