1
1
import { ActionIcon , Badge , createStyles , Paper , Skeleton , Title , Tooltip } from '@mantine/core' ;
2
2
import { Prisma } from '@prisma/client' ;
3
- import { IconEdit , IconRefresh , IconX } from '@tabler/icons-react' ;
3
+ import { IconEdit , IconExclamationMark , IconRefresh , IconX } from '@tabler/icons-react' ;
4
4
import { contrastColor } from 'contrast-color' ;
5
+ import { motion } from 'framer-motion' ;
5
6
import stc from 'string-to-color' ;
6
7
import { useRefreshModal } from './refreshMetadata' ;
7
8
import { useRemoveModal } from './removeManga' ;
@@ -59,6 +60,19 @@ const useStyles = createStyles((theme, _params, getRef) => ({
59
60
backgroundColor : theme . colors . gray [ 0 ] ,
60
61
} ,
61
62
} ,
63
+ outOfSyncClass : {
64
+ position : 'absolute' ,
65
+ alignContent : 'center' ,
66
+ display : 'flex' ,
67
+ flexWrap : 'wrap' ,
68
+ backgroundColor : theme . colors . red [ 6 ] ,
69
+ border : `2px solid ${ theme . white } ` ,
70
+ left : 8 ,
71
+ bottom : 8 ,
72
+ borderRadius : 9999 ,
73
+ width : 24 ,
74
+ height : 24 ,
75
+ } ,
62
76
editButton : {
63
77
ref : getRef ( 'editButton' ) ,
64
78
backgroundColor : theme . white ,
@@ -85,14 +99,16 @@ const useStyles = createStyles((theme, _params, getRef) => ({
85
99
} ,
86
100
} ) ) ;
87
101
88
- const mangaWithLibraryAndMetadata = Prisma . validator < Prisma . MangaArgs > ( ) ( {
89
- include : { library : true , metadata : true } ,
102
+ const mangaWithLibraryAndMetadataAndOutOfSyncChapters = Prisma . validator < Prisma . MangaArgs > ( ) ( {
103
+ include : { library : true , metadata : true , outOfSyncChapters : true } ,
90
104
} ) ;
91
105
92
- type MangaWithLibraryAndMetadata = Prisma . MangaGetPayload < typeof mangaWithLibraryAndMetadata > ;
106
+ type MangaWithLibraryAndMetadataAndOutOfSyncChapters = Prisma . MangaGetPayload <
107
+ typeof mangaWithLibraryAndMetadataAndOutOfSyncChapters
108
+ > ;
93
109
94
110
interface MangaCardProps {
95
- manga : MangaWithLibraryAndMetadata ;
111
+ manga : MangaWithLibraryAndMetadataAndOutOfSyncChapters ;
96
112
onRemove : ( shouldRemoveFiles : boolean ) => void ;
97
113
onUpdate : ( ) => void ;
98
114
onRefresh : ( ) => void ;
@@ -163,6 +179,35 @@ export function MangaCard({ manga, onRemove, onUpdate, onRefresh, onClick }: Man
163
179
< IconEdit size = { 18 } />
164
180
</ ActionIcon >
165
181
</ Tooltip >
182
+
183
+ { manga . outOfSyncChapters . length > 0 && (
184
+ < Tooltip withinPortal withArrow label = "This manga has out of sync chapters." position = "right" >
185
+ < motion . div
186
+ className = { classes . outOfSyncClass }
187
+ initial = { {
188
+ scale : 1 ,
189
+ } }
190
+ animate = { {
191
+ scale : [ 1.1 , 1.0 ] ,
192
+ } }
193
+ exit = { {
194
+ scale : 1 ,
195
+ } }
196
+ transition = { {
197
+ duration : 1 ,
198
+ repeat : Infinity ,
199
+ repeatType : 'loop' ,
200
+ type : 'spring' ,
201
+ stiffness : 400 ,
202
+ damping : 10 ,
203
+ repeatDelay : 3 ,
204
+ } }
205
+ >
206
+ < IconExclamationMark color = "white" strokeWidth = { 3 } />
207
+ </ motion . div >
208
+ </ Tooltip >
209
+ ) }
210
+
166
211
< div >
167
212
< Badge
168
213
sx = { { backgroundColor : stc ( manga . source ) , color : contrastColor ( { bgColor : stc ( manga . source ) } ) } }
0 commit comments