diff --git a/gameyfin/src/main/frontend/routes.tsx b/gameyfin/src/main/frontend/routes.tsx index 42c591f..40388e7 100644 --- a/gameyfin/src/main/frontend/routes.tsx +++ b/gameyfin/src/main/frontend/routes.tsx @@ -20,6 +20,7 @@ import InvitationRegistrationView from "Frontend/views/InvitationRegistrationVie import PluginManagement from "Frontend/components/administration/PluginManagement"; import {SystemManagement} from "Frontend/components/administration/SystemManagement"; import GameView from "Frontend/views/GameView"; +import LibraryManagementView from "Frontend/views/LibraryManagementView"; export const routes = protectRoutes([ { @@ -49,7 +50,14 @@ export const routes = protectRoutes([ path: 'administration', element: , children: [ - {path: 'libraries', element: }, + { + path: 'libraries', + element: , + children: [{ + path: 'library/:libraryId', + element: + }] + }, {path: 'users', element: }, {path: 'sso', element: }, {path: 'messages', element: }, diff --git a/gameyfin/src/main/frontend/views/GameView.tsx b/gameyfin/src/main/frontend/views/GameView.tsx index 42f7fbe..0c4a120 100644 --- a/gameyfin/src/main/frontend/views/GameView.tsx +++ b/gameyfin/src/main/frontend/views/GameView.tsx @@ -1,6 +1,6 @@ import {useEffect, useState} from "react"; import GameDto from "Frontend/generated/de/grimsi/gameyfin/games/dto/GameDto"; -import {GameEndpoint} from "Frontend/generated/endpoints"; +import {DownloadProviderEndpoint, GameEndpoint} from "Frontend/generated/endpoints"; import {useParams} from "react-router"; import {GameCover} from "Frontend/components/general/covers/GameCover"; import ComboButton, {ComboButtonOption} from "Frontend/components/general/input/ComboButton"; @@ -13,24 +13,23 @@ export default function GameView() { const {gameId} = useParams(); const [game, setGame] = useState(); + const [downloadOptions, setDownloadOptions] = useState>({}); - const downloadOptions: Record = { - browser: { - label: "Direct Download", - description: "Download the game in this browser", - action: () => { - DownloadEndpoint.downloadGame(parseInt(gameId!), "de.grimsi.gameyfin.plugins.directdownload.DirectDownloadPlugin$DirectDownloadProvider") - } - }, - torrent: { - label: "Torrent Download", - description: "Download the game as a torrent", - action: () => { - alert("Torrent download not yet implemented") - }, - isDisabled: true - } - } + useEffect(() => { + DownloadProviderEndpoint.getProviders().then((providers) => { + const options: Record = providers.reduce((acc, provider) => { + acc[provider.key] = { + label: provider.name, + description: provider.shortDescription ?? provider.description, + action: () => { + if (gameId) DownloadEndpoint.downloadGame(parseInt(gameId!), provider.key); + }, + }; + return acc; + }, {} as Record); + setDownloadOptions(options); + }); + }, []); useEffect(() => { if (gameId) { diff --git a/gameyfin/src/main/frontend/views/LibraryManagementView.tsx b/gameyfin/src/main/frontend/views/LibraryManagementView.tsx new file mode 100644 index 0000000..2d7cacb --- /dev/null +++ b/gameyfin/src/main/frontend/views/LibraryManagementView.tsx @@ -0,0 +1,7 @@ +import {useParams} from "react-router"; + +export default function LibraryManagementView() { + const {libraryId} = useParams(); + + return (<>); +} \ No newline at end of file diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadEndpoint.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadEndpoint.kt index 1695895..4d6ca24 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadEndpoint.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadEndpoint.kt @@ -15,10 +15,6 @@ class DownloadEndpoint( private val downloadService: DownloadService, private val gameService: GameService ) { - fun getProviders(): List { - return downloadService.getProviders() - } - @GetMapping("/{gameId}") fun downloadGame( @PathVariable gameId: Long, diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadProviderDto.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadProviderDto.kt new file mode 100644 index 0000000..db7c7dc --- /dev/null +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadProviderDto.kt @@ -0,0 +1,11 @@ +package de.grimsi.gameyfin.core.download + +import com.fasterxml.jackson.annotation.JsonInclude + +@JsonInclude(JsonInclude.Include.NON_NULL) +data class DownloadProviderDto( + val key: String, + val name: String, + val description: String, + val shortDescription: String? = null +) diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadProviderEndpoint.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadProviderEndpoint.kt new file mode 100644 index 0000000..d38aacb --- /dev/null +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadProviderEndpoint.kt @@ -0,0 +1,14 @@ +package de.grimsi.gameyfin.core.download + +import com.vaadin.hilla.Endpoint +import jakarta.annotation.security.PermitAll + +@Endpoint +@PermitAll +class DownloadProviderEndpoint( + private val downloadService: DownloadService +) { + fun getProviders(): List { + return downloadService.getProviders() + } +} \ No newline at end of file diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadService.kt index d86fe4e..81b9ab4 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/download/DownloadService.kt @@ -1,5 +1,6 @@ package de.grimsi.gameyfin.core.download +import de.grimsi.gameyfin.core.plugins.management.GameyfinPluginDescriptor import de.grimsi.gameyfin.core.plugins.management.GameyfinPluginManager import de.grimsi.gameyfin.pluginapi.download.Download import de.grimsi.gameyfin.pluginapi.download.DownloadProvider @@ -13,8 +14,18 @@ class DownloadService( private val downloadPlugins: List get() = pluginManager.getExtensions(DownloadProvider::class.java) - fun getProviders(): List { - return downloadPlugins.map { it.javaClass.name } + fun getProviders(): List { + return downloadPlugins.map { + val plugin = pluginManager.whichPlugin(it.javaClass.enclosingClass) + val descriptor = plugin.descriptor as GameyfinPluginDescriptor + + DownloadProviderDto( + key = it.javaClass.name, + name = descriptor.pluginName, + description = descriptor.pluginDescription, + shortDescription = descriptor.pluginShortDescription, + ) + } } fun getDownload(path: String, provider: String): Download { diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/PluginService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/PluginService.kt index f3b89ce..7ce1d0c 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/PluginService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/PluginService.kt @@ -59,11 +59,6 @@ class PluginService( .map { toDto(it) } } - fun getPluginManagementEntry(pluginId: String): PluginManagementEntry { - return pluginManagementRepository.findByIdOrNull(pluginId) - ?: throw IllegalArgumentException("Plugin with ID $pluginId not found") - } - fun getPluginManagementEntry(clazz: Class): PluginManagementEntry { val pluginWrapper = pluginManager.whichPlugin(clazz) return pluginManagementRepository.findByIdOrNull(pluginWrapper.pluginId) @@ -137,6 +132,11 @@ class PluginService( return pluginManager.validatePluginConfig(pluginId, configToValidate) } + private fun getPluginManagementEntry(pluginId: String): PluginManagementEntry { + return pluginManagementRepository.findByIdOrNull(pluginId) + ?: throw IllegalArgumentException("Plugin with ID $pluginId not found") + } + private fun toDto(pluginWrapper: PluginWrapper): PluginDto { val pluginManagementEntry = getPluginManagementEntry(pluginWrapper.pluginId) diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt index aafdeb3..99e8a05 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt @@ -183,7 +183,7 @@ class GameService( // Sort results by plugin priority val sortedResults = results.entries.sortedByDescending { - pluginService.getPluginManagementEntry(it.key.javaClass).priority + providerToManagementEntry[it.key]?.priority } sortedResults.forEach { (provider, metadata) -> diff --git a/plugins/directdownload/src/main/resources/MANIFEST.MF b/plugins/directdownload/src/main/resources/MANIFEST.MF index 36a2de7..252addc 100644 --- a/plugins/directdownload/src/main/resources/MANIFEST.MF +++ b/plugins/directdownload/src/main/resources/MANIFEST.MF @@ -1,10 +1,10 @@ -Plugin-Version: 1.0.0-alpha2 +Plugin-Version: 1.0.0-alpha3 Plugin-Class: de.grimsi.gameyfin.plugins.directdownload.DirectDownloadPlugin Plugin-Id: de.grimsi.gameyfin.directdownload Plugin-Name: Direct Download Plugin-Description: Downloads games directly in the browser.
If the game is contained in a folder, it will pack the folder into a zip file on the fly. -Plugin-Short-Description: Download games directly in the browser +Plugin-Short-Description: Download directly in the browser Plugin-Author: grimsi Plugin-License: MIT Plugin-Url: https://github.com/gameyfin