mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-13 16:40:01 +00:00
Load download options dynamically from backend
Minor layout and performance improvements
This commit is contained in:
@@ -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: <AdministrationView/>,
|
||||
children: [
|
||||
{path: 'libraries', element: <LibraryManagement/>},
|
||||
{
|
||||
path: 'libraries',
|
||||
element: <LibraryManagement/>,
|
||||
children: [{
|
||||
path: 'library/:libraryId',
|
||||
element: <LibraryManagementView/>
|
||||
}]
|
||||
},
|
||||
{path: 'users', element: <UserManagement/>},
|
||||
{path: 'sso', element: <SsoManagement/>},
|
||||
{path: 'messages', element: <MessageManagement/>},
|
||||
|
||||
@@ -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<GameDto>();
|
||||
const [downloadOptions, setDownloadOptions] = useState<Record<string, ComboButtonOption>>({});
|
||||
|
||||
const downloadOptions: Record<string, ComboButtonOption> = {
|
||||
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<string, ComboButtonOption> = 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<string, ComboButtonOption>);
|
||||
setDownloadOptions(options);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (gameId) {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import {useParams} from "react-router";
|
||||
|
||||
export default function LibraryManagementView() {
|
||||
const {libraryId} = useParams();
|
||||
|
||||
return (<></>);
|
||||
}
|
||||
@@ -15,10 +15,6 @@ class DownloadEndpoint(
|
||||
private val downloadService: DownloadService,
|
||||
private val gameService: GameService
|
||||
) {
|
||||
fun getProviders(): List<String> {
|
||||
return downloadService.getProviders()
|
||||
}
|
||||
|
||||
@GetMapping("/{gameId}")
|
||||
fun downloadGame(
|
||||
@PathVariable gameId: Long,
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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<DownloadProviderDto> {
|
||||
return downloadService.getProviders()
|
||||
}
|
||||
}
|
||||
@@ -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<DownloadProvider>
|
||||
get() = pluginManager.getExtensions(DownloadProvider::class.java)
|
||||
|
||||
fun getProviders(): List<String> {
|
||||
return downloadPlugins.map { it.javaClass.name }
|
||||
fun getProviders(): List<DownloadProviderDto> {
|
||||
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 {
|
||||
|
||||
@@ -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<ExtensionPoint>): 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)
|
||||
|
||||
|
||||
@@ -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) ->
|
||||
|
||||
@@ -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.<br>
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user