From b1dd4cb8c1e4402bdb421b4c1bdf7c523e37df43 Mon Sep 17 00:00:00 2001 From: grimsi <9295182+grimsi@users.noreply.github.com> Date: Sat, 14 Jun 2025 15:20:49 +0200 Subject: [PATCH] Finish game metadata editing Add comment field to GameView --- .../components/general/input/ArrayInput.tsx | 2 +- .../general/modals/EditGameMetadataModal.tsx | 44 ++++++- gameyfin/src/main/frontend/views/GameView.tsx | 107 +++++++++++++++--- .../de/grimsi/gameyfin/games/GameService.kt | 61 +++++++++- .../gameyfin/games/dto/GameUpdateDto.kt | 7 ++ 5 files changed, 203 insertions(+), 18 deletions(-) diff --git a/gameyfin/src/main/frontend/components/general/input/ArrayInput.tsx b/gameyfin/src/main/frontend/components/general/input/ArrayInput.tsx index b3fd2e7..d5c904b 100644 --- a/gameyfin/src/main/frontend/components/general/input/ArrayInput.tsx +++ b/gameyfin/src/main/frontend/components/general/input/ArrayInput.tsx @@ -27,7 +27,7 @@ const ArrayInput = ({label, ...props}) => { } return ( -
+

{label}

{field.value.length} {field.value.length == 1 ? "element" : "elements"} diff --git a/gameyfin/src/main/frontend/components/general/modals/EditGameMetadataModal.tsx b/gameyfin/src/main/frontend/components/general/modals/EditGameMetadataModal.tsx index 8de7070..6261139 100644 --- a/gameyfin/src/main/frontend/components/general/modals/EditGameMetadataModal.tsx +++ b/gameyfin/src/main/frontend/components/general/modals/EditGameMetadataModal.tsx @@ -1,5 +1,14 @@ import GameDto from "Frontend/generated/de/grimsi/gameyfin/games/dto/GameDto"; -import {Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react"; +import { + Accordion, + AccordionItem, + Button, + Modal, + ModalBody, + ModalContent, + ModalFooter, + ModalHeader +} from "@heroui/react"; import {Form, Formik} from "formik"; import Input from "Frontend/components/general/input/Input"; import React from "react"; @@ -7,9 +16,10 @@ import GameUpdateDto from "Frontend/generated/de/grimsi/gameyfin/games/dto/GameU import {deepDiff} from "Frontend/util/utils"; import {GameEndpoint} from "Frontend/generated/endpoints"; import TextAreaInput from "Frontend/components/general/input/TextAreaInput"; -import DatePickerInput from "Frontend/components/general/input/DatePickerInput"; import * as Yup from "yup"; import GameCoverPicker from "Frontend/components/general/input/GameCoverPicker"; +import DatePickerInput from "Frontend/components/general/input/DatePickerInput"; +import ArrayInput from "Frontend/components/general/input/ArrayInput"; interface EditGameMetadataModalProps { game: GameDto; @@ -53,12 +63,40 @@ export default function EditGameMetadataModal({game, isOpen, onOpenChange}: Edit
- +
+ + +
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + - } + + + + + + + + + +
} {downloadOptions &&
+ {game.comment && + + }> + + {props.children} + + } + }} + >{game.comment} + + + }

Summary

@@ -112,11 +187,14 @@ export default function GameView() { Developed by {game.developers && game.developers.length > 0 - ? [...game.developers].sort().map(dev => - - {dev} - + ? [...game.developers].sort().map((dev, index) => + <> + + {dev} + + {index !== game.developers!!.length - 1 &&

/

} + ) : @@ -195,6 +273,9 @@ export default function GameView() {
+ companyService.createOrGet(Company(name = name, type = CompanyType.DEVELOPER)) } + existingGame.metadata.fields["developers"]?.source = GameFieldUserSource(user = user) + } + gameUpdateDto.publishers?.let { + existingGame.publishers = + it.map { name -> companyService.createOrGet(Company(name = name, type = CompanyType.PUBLISHER)) } + existingGame.metadata.fields["publishers"]?.source = GameFieldUserSource(user = user) + } + gameUpdateDto.genres?.let { + existingGame.genres = it.mapNotNull { name -> + try { + Genre.valueOf(name) + } catch (_: IllegalArgumentException) { + log.error { "Invalid value for genre '$name', must be one of ${Genre.entries}" } + null + } + } + existingGame.metadata.fields["genres"]?.source = GameFieldUserSource(user = user) + } + gameUpdateDto.themes?.let { + existingGame.themes = it.mapNotNull { name -> + try { + Theme.valueOf(name) + } catch (_: IllegalArgumentException) { + log.error { "Invalid value for theme '$name', must be one of ${Theme.entries}" } + null + } + } + existingGame.metadata.fields["themes"]?.source = GameFieldUserSource(user = user) + } + gameUpdateDto.keywords?.let { + existingGame.keywords = it + existingGame.metadata.fields["keywords"]?.source = GameFieldUserSource(user = user) + } + gameUpdateDto.features?.let { + existingGame.features = it.mapNotNull { name -> + try { + GameFeature.valueOf(name) + } catch (_: IllegalArgumentException) { + log.error { "Invalid value for feature '$name', must be one of ${GameFeature.entries}" } + null + } + } + existingGame.metadata.fields["features"]?.source = GameFieldUserSource(user = user) + } + gameUpdateDto.perspectives?.let { + existingGame.perspectives = it.mapNotNull { name -> + try { + PlayerPerspective.valueOf(name) + } catch (_: IllegalArgumentException) { + log.error { "Invalid value for perspective '$name', must be one of ${PlayerPerspective.entries}" } + null + } + } + existingGame.metadata.fields["perspectives"]?.source = GameFieldUserSource(user = user) + } gameUpdateDto.metadata?.let { metadata -> diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/dto/GameUpdateDto.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/dto/GameUpdateDto.kt index ad6e5b9..c8dd4c7 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/dto/GameUpdateDto.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/dto/GameUpdateDto.kt @@ -9,5 +9,12 @@ data class GameUpdateDto( val coverUrl: String?, val comment: String?, val summary: String?, + val developers: List?, + val publishers: List?, + val genres: List?, + val themes: List?, + val keywords: List?, + val features: List?, + val perspectives: List?, val metadata: GameUpdateMetadataDto? ) \ No newline at end of file