diff --git a/src/components/Common/Badge/index.tsx b/src/components/Common/Badge/index.tsx index ec13c05d0..17eda5b1d 100644 --- a/src/components/Common/Badge/index.tsx +++ b/src/components/Common/Badge/index.tsx @@ -9,8 +9,7 @@ interface BadgeProps { | 'warning' | 'success' | 'dark' - | 'light' - | 'gradient'; + | 'light'; className?: string; href?: string; children: React.ReactNode; @@ -67,11 +66,6 @@ const Badge = ( badgeStyle.push('hover:bg-gray-600'); } break; - case 'gradient': - badgeStyle.push( - 'border border-white bg-gradient-to-br from-indigo-600 to-purple-600 !text-indigo-100 shadow-black' - ); - break; default: badgeStyle.push( 'bg-indigo-500 bg-opacity-80 border border-indigo-500 !text-indigo-100' diff --git a/src/components/IssueDetails/index.tsx b/src/components/IssueDetails/index.tsx index 4fbe71452..171f90a81 100644 --- a/src/components/IssueDetails/index.tsx +++ b/src/components/IssueDetails/index.tsx @@ -31,8 +31,7 @@ import { useRouter } from 'next/router'; import { useState } from 'react'; import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl'; import { useToasts } from 'react-toast-notifications'; -import useSWR from 'swr'; -import useSWRMutation from 'swr/mutation'; +import useSWR, { mutate } from 'swr'; import * as Yup from 'yup'; const messages = defineMessages({ @@ -105,16 +104,6 @@ const IssueDetails = () => { (opt) => opt.issueType === issueData?.issueType ); - const fetchIssuesCount = async () => { - const response = await axios.get('/api/v1/request/count'); - return response.data; - }; - - const { trigger: issueTrigger } = useSWRMutation( - '/api/v1/issue/count', - fetchIssuesCount - ); - if (!data && !error) { return ; } @@ -155,7 +144,7 @@ const IssueDetails = () => { autoDismiss: true, }); revalidateIssue(); - issueTrigger(); + mutate('/api/v1/issue/count'); } catch (e) { addToast(intl.formatMessage(messages.toaststatusupdatefailed), { appearance: 'error', @@ -167,6 +156,7 @@ const IssueDetails = () => { const deleteIssue = async () => { try { await axios.delete(`/api/v1/issue/${issueData.id}`); + mutate('/api/v1/issue/count'); addToast(intl.formatMessage(messages.toastissuedeleted), { appearance: 'success', diff --git a/src/components/Layout/MobileMenu/index.tsx b/src/components/Layout/MobileMenu/index.tsx index c8b1f30bd..e288b8269 100644 --- a/src/components/Layout/MobileMenu/index.tsx +++ b/src/components/Layout/MobileMenu/index.tsx @@ -29,8 +29,8 @@ import { cloneElement, useRef, useState } from 'react'; import { useIntl } from 'react-intl'; interface MobileMenuProps { - pendingRequestsCount?: number; - openIssuesCount?: number; + pendingRequestsCount: number; + openIssuesCount: number; } interface MenuLink { @@ -170,24 +170,20 @@ const MobileMenu = ({ })} {link.content} {link.href === '/requests' && - pendingRequestsCount && pendingRequestsCount > 0 && hasPermission(Permission.MANAGE_REQUESTS) && (
- - {pendingRequestsCount < 100 - ? pendingRequestsCount - : '99+'} + + {pendingRequestsCount}
)} {link.href === '/issues' && - openIssuesCount && - openIssuesCount && + openIssuesCount > 0 && hasPermission(Permission.MANAGE_ISSUES) && (
- - {openIssuesCount < 100 ? openIssuesCount : '99+'} + + {openIssuesCount}
)} @@ -217,14 +213,18 @@ const MobileMenu = ({ } )} {link.href === '/requests' && - pendingRequestsCount && + pendingRequestsCount > 0 && hasPermission(Permission.MANAGE_REQUESTS) && ( -
- - {pendingRequestsCount < 100 - ? pendingRequestsCount - : '99+'} - +
+ + {pendingRequestsCount} +
)} diff --git a/src/components/Layout/Sidebar/index.tsx b/src/components/Layout/Sidebar/index.tsx index ce85f69ad..9aa2a5ee3 100644 --- a/src/components/Layout/Sidebar/index.tsx +++ b/src/components/Layout/Sidebar/index.tsx @@ -31,8 +31,8 @@ export const menuMessages = defineMessages({ interface SidebarProps { open?: boolean; setClosed: () => void; - pendingRequestsCount?: number; - openIssuesCount?: number; + pendingRequestsCount: number; + openIssuesCount: number; } interface SidebarLinkProps { @@ -263,26 +263,36 @@ const Sidebar = ({ menuMessages[sidebarLink.messagesKey] )} {sidebarLink.messagesKey === 'requests' && - pendingRequestsCount && pendingRequestsCount > 0 && hasPermission(Permission.MANAGE_REQUESTS) && (
- - {pendingRequestsCount < 100 - ? pendingRequestsCount - : '99+'} + + {pendingRequestsCount}
)} {sidebarLink.messagesKey === 'issues' && - openIssuesCount && openIssuesCount > 0 && hasPermission(Permission.MANAGE_ISSUES) && (
- - {openIssuesCount < 100 - ? openIssuesCount - : '99+'} + + {openIssuesCount}
)} diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index c3a3e2244..fd2c8c77a 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -58,22 +58,19 @@ const Layout = ({ children }: LayoutProps) => {
- {requestResponse && issueResponse && ( - setSidebarOpen(false)} - pendingRequestsCount={requestResponse.pending} - openIssuesCount={issueResponse.open} + setSidebarOpen(false)} + pendingRequestsCount={requestResponse?.pending} + openIssuesCount={issueResponse?.open} + /> +
+ - )} - {requestResponse && issueResponse && ( -
- -
- )} +
+
{ const { profile, rootFolder, server, languageProfile } = useRequestOverride(request); - const fetchRequestsCount = async () => { - const response = await axios.get('/api/v1/request/count'); - return response.data; - }; - - const { trigger: requestTrigger } = useSWRMutation( - '/api/v1/request/count', - fetchRequestsCount - ); - const updateRequest = async (type: 'approve' | 'decline'): Promise => { setIsUpdating(true); await axios.post(`/api/v1/request/${request.id}/${type}`); if (onUpdate) { onUpdate(); - requestTrigger(); + mutate('/api/v1/request/count'); } setIsUpdating(false); }; @@ -78,7 +68,7 @@ const RequestBlock = ({ request, onUpdate }: RequestBlockProps) => { if (onUpdate) { onUpdate(); - requestTrigger(); + mutate('/api/v1/request/count'); } setIsUpdating(false); diff --git a/src/components/RequestButton/index.tsx b/src/components/RequestButton/index.tsx index bf52398b9..5726df24f 100644 --- a/src/components/RequestButton/index.tsx +++ b/src/components/RequestButton/index.tsx @@ -15,7 +15,7 @@ import type { MediaRequest } from '@server/entity/MediaRequest'; import axios from 'axios'; import { useMemo, useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import useSWRMutation from 'swr/mutation'; +import { mutate } from 'swr'; const messages = defineMessages({ viewrequest: 'View Request', @@ -90,16 +90,6 @@ const RequestButton = ({ : undefined; }, [active4kRequests, user]); - const fetchRequestsCount = async () => { - const response = await axios.get('/api/v1/request/count'); - return response.data; - }; - - const { trigger: requestTrigger } = useSWRMutation( - '/api/v1/request/count', - fetchRequestsCount - ); - const modifyRequest = async ( request: MediaRequest, type: 'approve' | 'decline' @@ -108,7 +98,7 @@ const RequestButton = ({ if (response) { onUpdate(); - requestTrigger(); + mutate('/api/v1/request/count'); } }; @@ -127,7 +117,7 @@ const RequestButton = ({ ); onUpdate(); - requestTrigger(); + mutate('/api/v1/request/count'); }; const buttons: ButtonOption[] = []; diff --git a/src/components/RequestCard/index.tsx b/src/components/RequestCard/index.tsx index 7a9368a7a..4288af674 100644 --- a/src/components/RequestCard/index.tsx +++ b/src/components/RequestCard/index.tsx @@ -27,7 +27,6 @@ import { useInView } from 'react-intersection-observer'; import { defineMessages, useIntl } from 'react-intl'; import { useToasts } from 'react-toast-notifications'; import useSWR, { mutate } from 'swr'; -import useSWRMutation from 'swr/mutation'; const messages = defineMessages({ seasons: '{seasonCount, plural, one {Season} other {Seasons}}', @@ -76,6 +75,7 @@ const RequestCardError = ({ requestData }: RequestCardErrorProps) => { await axios.delete(`/api/v1/media/${requestData?.media.id}`); mutate('/api/v1/media?filter=allavailable&take=20&sort=mediaAdded'); mutate('/api/v1/request?filter=all&take=10&sort=modified&skip=0'); + mutate('/api/v1/request/count'); }; return ( @@ -248,29 +248,19 @@ const RequestCard = ({ request, onTitleData }: RequestCardProps) => { iOSPlexUrl4k: requestData?.media?.iOSPlexUrl4k, }); - const fetchRequestsCount = async () => { - const response = await axios.get('/api/v1/request/count'); - return response.data; - }; - - const { trigger: requestTrigger } = useSWRMutation( - '/api/v1/request/count', - fetchRequestsCount - ); - const modifyRequest = async (type: 'approve' | 'decline') => { const response = await axios.post(`/api/v1/request/${request.id}/${type}`); if (response) { revalidate(); - requestTrigger(); + mutate('/api/v1/request/count'); } }; const deleteRequest = async () => { await axios.delete(`/api/v1/request/${request.id}`); mutate('/api/v1/request?filter=all&take=10&sort=modified&skip=0'); - requestTrigger(); + mutate('/api/v1/request/count'); }; const retryRequest = async () => { diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx index 9f3b540f2..ee44d8778 100644 --- a/src/components/RequestList/RequestItem/index.tsx +++ b/src/components/RequestList/RequestItem/index.tsx @@ -25,8 +25,7 @@ import { useState } from 'react'; import { useInView } from 'react-intersection-observer'; import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl'; import { useToasts } from 'react-toast-notifications'; -import useSWR from 'swr'; -import useSWRMutation from 'swr/mutation'; +import useSWR, { mutate } from 'swr'; const messages = defineMessages({ seasons: '{seasonCount, plural, one {Season} other {Seasons}}', @@ -63,6 +62,7 @@ const RequestItemError = ({ const deleteRequest = async () => { await axios.delete(`/api/v1/media/${requestData?.media.id}`); revalidateList(); + mutate('/api/v1/request/count'); }; const { plexUrl, plexUrl4k } = useDeepLinks({ @@ -307,22 +307,12 @@ const RequestItem = ({ request, revalidateList }: RequestItemProps) => { const [isRetrying, setRetrying] = useState(false); - const fetchRequestsCount = async () => { - const response = await axios.get('/api/v1/request/count'); - return response.data; - }; - - const { trigger: requestTrigger } = useSWRMutation( - '/api/v1/request/count', - fetchRequestsCount - ); - const modifyRequest = async (type: 'approve' | 'decline') => { const response = await axios.post(`/api/v1/request/${request.id}/${type}`); if (response) { revalidate(); - requestTrigger(); + mutate('/api/v1/request/count'); } }; @@ -330,7 +320,7 @@ const RequestItem = ({ request, revalidateList }: RequestItemProps) => { await axios.delete(`/api/v1/request/${request.id}`); revalidateList(); - requestTrigger(); + mutate('/api/v1/request/count'); }; const retryRequest = async () => { diff --git a/src/components/RequestModal/CollectionRequestModal.tsx b/src/components/RequestModal/CollectionRequestModal.tsx index e2c301000..26dc410d4 100644 --- a/src/components/RequestModal/CollectionRequestModal.tsx +++ b/src/components/RequestModal/CollectionRequestModal.tsx @@ -16,7 +16,7 @@ import axios from 'axios'; import { useCallback, useEffect, useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useToasts } from 'react-toast-notifications'; -import useSWR from 'swr'; +import useSWR, { mutate } from 'swr'; const messages = defineMessages({ requestadmin: 'This request will be approved automatically.', @@ -36,7 +36,6 @@ interface RequestModalProps extends React.HTMLAttributes { onCancel?: () => void; onComplete?: (newStatus: MediaStatus) => void; onUpdating?: (isUpdating: boolean) => void; - requestTrigger: () => void; } const CollectionRequestModal = ({ @@ -45,7 +44,6 @@ const CollectionRequestModal = ({ tmdbId, onUpdating, is4k = false, - requestTrigger, }: RequestModalProps) => { const [isUpdating, setIsUpdating] = useState(false); const [requestOverrides, setRequestOverrides] = @@ -213,7 +211,7 @@ const CollectionRequestModal = ({ ? MediaStatus.UNKNOWN : MediaStatus.PARTIALLY_AVAILABLE ); - requestTrigger(); + mutate('/api/v1/request/count'); } addToast( @@ -242,7 +240,6 @@ const CollectionRequestModal = ({ intl, selectedParts, is4k, - requestTrigger, ]); const hasAutoApprove = hasPermission( diff --git a/src/components/RequestModal/MovieRequestModal.tsx b/src/components/RequestModal/MovieRequestModal.tsx index 770bcc6a5..cd196576d 100644 --- a/src/components/RequestModal/MovieRequestModal.tsx +++ b/src/components/RequestModal/MovieRequestModal.tsx @@ -42,7 +42,6 @@ interface RequestModalProps extends React.HTMLAttributes { onCancel?: () => void; onComplete?: (newStatus: MediaStatus) => void; onUpdating?: (isUpdating: boolean) => void; - requestTrigger: () => void; } const MovieRequestModal = ({ @@ -52,7 +51,6 @@ const MovieRequestModal = ({ onUpdating, editRequest, is4k = false, - requestTrigger, }: RequestModalProps) => { const [isUpdating, setIsUpdating] = useState(false); const [requestOverrides, setRequestOverrides] = @@ -97,7 +95,7 @@ const MovieRequestModal = ({ ...overrideParams, }); mutate('/api/v1/request?filter=all&take=10&sort=modified&skip=0'); - requestTrigger(); + mutate('/api/v1/request/count'); if (response.data) { if (onComplete) { @@ -137,7 +135,6 @@ const MovieRequestModal = ({ data?.id, data?.title, is4k, - requestTrigger, onComplete, addToast, intl, @@ -152,7 +149,7 @@ const MovieRequestModal = ({ `/api/v1/request/${editRequest?.id}` ); mutate('/api/v1/request?filter=all&take=10&sort=modified&skip=0'); - requestTrigger(); + mutate('/api/v1/request/count'); if (response.status === 204) { if (onComplete) { @@ -190,7 +187,7 @@ const MovieRequestModal = ({ await axios.post(`/api/v1/request/${editRequest?.id}/approve`); } mutate('/api/v1/request?filter=all&take=10&sort=modified&skip=0'); - requestTrigger(); + mutate('/api/v1/request/count'); addToast( diff --git a/src/components/RequestModal/TvRequestModal.tsx b/src/components/RequestModal/TvRequestModal.tsx index 3e5203697..166288c75 100644 --- a/src/components/RequestModal/TvRequestModal.tsx +++ b/src/components/RequestModal/TvRequestModal.tsx @@ -56,7 +56,6 @@ interface RequestModalProps extends React.HTMLAttributes { onCancel?: () => void; onComplete?: (newStatus: MediaStatus) => void; onUpdating?: (isUpdating: boolean) => void; - requestTrigger: () => void; is4k?: boolean; editRequest?: MediaRequest; } @@ -68,7 +67,6 @@ const TvRequestModal = ({ onUpdating, editRequest, is4k = false, - requestTrigger, }: RequestModalProps) => { const settings = useSettings(); const { addToast } = useToasts(); @@ -108,7 +106,7 @@ const TvRequestModal = ({ if (onUpdating) { onUpdating(true); - requestTrigger(); + mutate('/api/v1/request/count'); } try { @@ -131,7 +129,7 @@ const TvRequestModal = ({ await axios.delete(`/api/v1/request/${editRequest.id}`); } mutate('/api/v1/request?filter=all&take=10&sort=modified&skip=0'); - requestTrigger(); + mutate('/api/v1/request/count'); addToast( @@ -180,7 +178,7 @@ const TvRequestModal = ({ if (onUpdating) { onUpdating(true); - requestTrigger(); + mutate('/api/v1/request/count'); } try { diff --git a/src/components/RequestModal/index.tsx b/src/components/RequestModal/index.tsx index 828aa443f..9ef6b4057 100644 --- a/src/components/RequestModal/index.tsx +++ b/src/components/RequestModal/index.tsx @@ -4,8 +4,6 @@ import TvRequestModal from '@app/components/RequestModal/TvRequestModal'; import { Transition } from '@headlessui/react'; import type { MediaStatus } from '@server/constants/media'; import type { MediaRequest } from '@server/entity/MediaRequest'; -import axios from 'axios'; -import useSWRMutation from 'swr/mutation'; interface RequestModalProps { show: boolean; @@ -28,16 +26,6 @@ const RequestModal = ({ onUpdating, onCancel, }: RequestModalProps) => { - const fetchRequestsCount = async () => { - const response = await axios.get('/api/v1/request/count'); - return response.data; - }; - - const { trigger: requestTrigger } = useSWRMutation( - '/api/v1/request/count', - fetchRequestsCount - ); - return ( ) : type === 'tv' ? ( ) : ( )}