Skip to content

Commit aab89f9

Browse files
committed
feat: have list of comics an item is featured in
Closes #19
1 parent 0bcad3c commit aab89f9

7 files changed

Lines changed: 218 additions & 4 deletions

File tree

.prettierignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ node_modules
22

33
# Ignore artifacts:
44
build
5-
coverage
5+
coverage
6+
7+
dist
8+
storybook-static

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
- Add guest comic/non-canon pills to `ComicList`
1313
- Add Storybook link to README
14+
- Added list of comics an item is featured in. Closes [#19](https://github.com/Questionable-Content-Extensions/client/issues/19)
1415

1516
### Changed 🔧
1617

src/components/GoToComicDialog/CollapsibleDetails/CollapsibleDetails.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@ export default function CollapsibleDetails({
55
children,
66
initiallyOpen,
77
indentChildren,
8+
onToggle,
89
}: {
910
summary: string
1011
children: React.ReactNode
1112
initiallyOpen?: boolean
1213
indentChildren?: boolean
14+
onToggle?: React.ReactEventHandler<HTMLDetailsElement>
1315
}) {
1416
return (
15-
<details className={styles.details} open={initiallyOpen}>
17+
<details
18+
className={styles.details}
19+
open={initiallyOpen}
20+
onToggle={onToggle}
21+
>
1622
<summary className="py-4 mb-2 flex items-center font-bold border-0 border-b border-solid border-gray-200">
1723
{summary}
1824
<button className="ml-auto">

src/components/ItemDetailsDialog/ItemDetailsDialog.stories.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
import Settings from '~/settings'
2020

2121
import ItemDetailsDialog from './ItemDetailsDialog'
22+
import { FAYE_COMICS } from '../../mocks'
2223

2324
const fayeImage: any = require('./4.png')
2425

@@ -139,6 +140,16 @@ const Template: StoryFn<typeof ItemDetailsDialog> = function (
139140
)
140141
}
141142
),
143+
rest.get(
144+
'http://localhost:3000/api/v2/itemdata/:itemId/comics',
145+
(req, res, ctx) => {
146+
//const { itemId } = req.params
147+
return res(
148+
ctx.delay(1000 + Math.random() * 1000),
149+
ctx.json(FAYE_COMICS)
150+
)
151+
}
152+
),
142153
rest.get(
143154
'http://localhost:3000/api/v2/itemdata/:itemId/images',
144155
(req, res, ctx) => {

src/components/ItemDetailsDialog/ItemDetailsDialog.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from '@store/api/comicApiSlice'
1717
import {
1818
useAllDataQuery,
19+
useComicsQuery,
1920
useDeleteImageMutation,
2021
useSetPrimaryImageMutation,
2122
useUploadImageMutation,
@@ -32,6 +33,7 @@ import { AppDispatch, RootState } from '@store/store'
3233
import constants from '~/constants'
3334

3435
import ItemDataPanel from './ItemDataPanel/ItemDataPanel'
36+
import ComicList from '@components/GoToComicDialog/ComicList/ComicList'
3537

3638
const mapState = (state: RootState) => {
3739
return {
@@ -63,8 +65,6 @@ type ItemDetailsDialogProps = PropsFromRedux & {
6365
initialItemId: number | null
6466
}
6567

66-
// TODO: Find a way to list all comics this item is in
67-
6868
function ItemDetailsDialog({
6969
settings,
7070
editorItemId,
@@ -161,6 +161,11 @@ function ItemDetailsDialog({
161161
: skipToken
162162
)
163163

164+
const [loadComics, setLoadComics] = useState(false)
165+
const { data: itemComics, isLoading: itemComicsIsLoading } = useComicsQuery(
166+
loadComics && currentItemId ? { itemId: currentItemId } : skipToken
167+
)
168+
164169
return (
165170
<ModalDialog
166171
onCloseClicked={onClose}
@@ -188,6 +193,7 @@ function ItemDetailsDialog({
188193
onClose()
189194
}}
190195
onShowItemData={(itemId: ItemId) => {
196+
setLoadComics(false)
191197
setCurrentItemId(itemId)
192198
}}
193199
onDeleteImage={(imageId: number) => {
@@ -210,6 +216,26 @@ function ItemDetailsDialog({
210216
onUploadImage={uploadImage}
211217
isUploadingImage={isUploadingImage}
212218
/>
219+
<CollapsibleDetails
220+
summary="Comics item is featured in"
221+
onToggle={(e) => {
222+
setLoadComics(e.currentTarget.open)
223+
}}
224+
initiallyOpen={loadComics}
225+
>
226+
<ComicList
227+
allComicData={itemComics ?? []}
228+
isLoading={itemComicsIsLoading}
229+
subDivideGotoComics={
230+
settings?.subDivideGotoComics ?? true
231+
}
232+
onGoToComic={(comic) => {
233+
setLoadComics(false)
234+
setCurrentComic(comic)
235+
onClose()
236+
}}
237+
/>
238+
</CollapsibleDetails>
213239
{settings?.editMode ? (
214240
<CollapsibleDetails summary="Edit log for item">
215241
<EditLogPanel

src/mocks.ts

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,150 @@ export const FAYE_LOCATIONS: RelatedItem[] = [
272272
},
273273
]
274274

275+
export const FAYE_COMICS: ComicList[] = [
276+
{
277+
comic: 4805,
278+
title: 'Messy Joseph',
279+
tagline: 'say no more',
280+
isNonCanon: false,
281+
isGuestComic: false,
282+
},
283+
{
284+
comic: 4801,
285+
title: 'Five Bars',
286+
tagline: "it's the little things",
287+
isNonCanon: false,
288+
isGuestComic: false,
289+
},
290+
{
291+
comic: 4800,
292+
title: 'Fumigation',
293+
tagline: 'smells kinda mustardy',
294+
isNonCanon: false,
295+
isGuestComic: false,
296+
},
297+
{
298+
comic: 4799,
299+
title: 'Intestinal Fortitude',
300+
tagline: 'just a gut feeling',
301+
isNonCanon: false,
302+
isGuestComic: false,
303+
},
304+
{
305+
comic: 4798,
306+
title: 'Beast Mode',
307+
tagline: 'then the hyenas came',
308+
isNonCanon: false,
309+
isGuestComic: false,
310+
},
311+
{
312+
comic: 4796,
313+
title: 'Pollen',
314+
tagline: 'just a sneeze',
315+
isNonCanon: false,
316+
isGuestComic: false,
317+
},
318+
{
319+
comic: 4795,
320+
title: 'The Brute Force Method',
321+
tagline: 'do not try this at home',
322+
isNonCanon: false,
323+
isGuestComic: false,
324+
},
325+
{
326+
comic: 4794,
327+
title: 'Skull Buddy',
328+
tagline: 'explains a lot',
329+
isNonCanon: false,
330+
isGuestComic: false,
331+
},
332+
{
333+
comic: 4793,
334+
title: 'Self-Diagnostic',
335+
tagline: 'haha woo',
336+
isNonCanon: false,
337+
isGuestComic: false,
338+
},
339+
{
340+
comic: 4792,
341+
title: 'Heat Shrink',
342+
tagline: "it's just really fancy shrinkwrap",
343+
isNonCanon: false,
344+
isGuestComic: false,
345+
},
346+
{
347+
comic: 4791,
348+
title: 'Does A Body Good',
349+
tagline: 'humans are like 80% goop, robots are about 20%',
350+
isNonCanon: false,
351+
isGuestComic: false,
352+
},
353+
{
354+
comic: 4790,
355+
title: 'Renowned Entomologist',
356+
tagline: 'some never before known to science',
357+
isNonCanon: false,
358+
isGuestComic: false,
359+
},
360+
{
361+
comic: 4778,
362+
title: 'Frankenmelon',
363+
tagline: 'SO smug',
364+
isNonCanon: false,
365+
isGuestComic: false,
366+
},
367+
{
368+
comic: 4727,
369+
title: 'Stick The Pose',
370+
tagline: 'who could have foreseen this',
371+
isNonCanon: false,
372+
isGuestComic: false,
373+
},
374+
{
375+
comic: 4716,
376+
title: 'Exit Strategy',
377+
tagline: 'in reality, bears shit pretty much wherever they feel like',
378+
isNonCanon: false,
379+
isGuestComic: false,
380+
},
381+
{
382+
comic: 4712,
383+
title: 'The Straight And Narrow',
384+
tagline: 'crimes and bad decisions are not necessarily the same thing',
385+
isNonCanon: false,
386+
isGuestComic: false,
387+
},
388+
{
389+
comic: 4711,
390+
title: 'The Dankest Emmett Lore',
391+
tagline:
392+
"either Emmett rules or they're a really creative liar. or both",
393+
isNonCanon: false,
394+
isGuestComic: false,
395+
},
396+
{
397+
comic: 4710,
398+
title: 'More Emmett Lore',
399+
tagline: 'the cool S...',
400+
isNonCanon: false,
401+
isGuestComic: false,
402+
},
403+
{
404+
comic: 4705,
405+
title: 'Pupating',
406+
tagline: 'babies freak me out',
407+
isNonCanon: false,
408+
isGuestComic: false,
409+
},
410+
{
411+
comic: 4704,
412+
title: 'Wind-Blown',
413+
tagline: 'all other emotions are a subset of either chomp or awoo',
414+
isNonCanon: false,
415+
isGuestComic: false,
416+
},
417+
]
418+
275419
export const MANY_IMAGES: ItemImageList[] = [
276420
{ id: 1, crc32cHash: 0 },
277421
{ id: 2, crc32cHash: 0 },

src/store/api/itemApiSlice.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ComicList } from '@models/ComicList'
12
import { DeleteImageBody } from '@models/DeleteImageBody'
23
import { ImageId } from '@models/ImageId'
34
import { Item } from '@models/Item'
@@ -69,6 +70,27 @@ export const itemApiSlice = apiSlice.injectEndpoints({
6970
]
7071
: [],
7172
}),
73+
comics: builder.query<ComicList[], GetDataQueryArgs>({
74+
query: ({ itemId }) => {
75+
return {
76+
url: `${constants.itemDataEndpoint}${itemId}/comics`,
77+
}
78+
},
79+
transformResponse: transformResponseByJsonParseResultText,
80+
providesTags: (result, _error, args) =>
81+
result
82+
? [
83+
{
84+
type: 'Item',
85+
id: `${args.itemId}-comics`,
86+
},
87+
{
88+
type: 'Item',
89+
id: `${args.itemId}-data`,
90+
},
91+
]
92+
: [],
93+
}),
7294
imageData: builder.query<ItemImageList[], GetDataQueryArgs>({
7395
query: ({ itemId }) => {
7496
return {
@@ -284,6 +306,7 @@ export const itemApiSlice = apiSlice.injectEndpoints({
284306
export const {
285307
useAllItemsQuery,
286308
useGetItemDataQuery,
309+
useComicsQuery,
287310
useImageDataQuery,
288311
useFriendDataQuery,
289312
useLocationDataQuery,

0 commit comments

Comments
 (0)