From c365574a9228c57eeb267a3892349117325e4067 Mon Sep 17 00:00:00 2001 From: grimsi <9295182+grimsi@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:34:01 +0100 Subject: [PATCH] Implement plugin enabling & disabling --- .../administration/PluginManagement.tsx | 9 +++- .../components/general/PluginDetailsModal.tsx | 4 +- .../general/PluginManagementCard.tsx | 54 ++++++++++++++++--- .../DatabasePluginStatusProvider.kt | 4 +- .../management/GameyfinPluginManager.kt | 13 ++++- .../management/PluginManagementEndpoint.kt | 2 + .../management/PluginManagementService.kt | 11 ++++ 7 files changed, 85 insertions(+), 12 deletions(-) diff --git a/gameyfin/src/main/frontend/components/administration/PluginManagement.tsx b/gameyfin/src/main/frontend/components/administration/PluginManagement.tsx index 1e00686..2abf2c1 100644 --- a/gameyfin/src/main/frontend/components/administration/PluginManagement.tsx +++ b/gameyfin/src/main/frontend/components/administration/PluginManagement.tsx @@ -14,6 +14,10 @@ export default function PluginManagement() { }); }, []); + function updatePlugin(plugin: PluginDto) { + setPlugins(plugins.map(p => p.id === plugin.id ? plugin : p)); + } + return (
@@ -26,7 +30,10 @@ export default function PluginManagement() {
- {plugins.map((plugin) => )} + {plugins.map((plugin) => + )}
diff --git a/gameyfin/src/main/frontend/components/general/PluginDetailsModal.tsx b/gameyfin/src/main/frontend/components/general/PluginDetailsModal.tsx index 9240304..51882c9 100644 --- a/gameyfin/src/main/frontend/components/general/PluginDetailsModal.tsx +++ b/gameyfin/src/main/frontend/components/general/PluginDetailsModal.tsx @@ -6,7 +6,7 @@ import {PluginConfigEndpoint} from "Frontend/generated/endpoints"; import PluginDto from "Frontend/generated/de/grimsi/gameyfin/core/plugins/management/PluginDto"; import PluginConfigElement from "Frontend/generated/de/grimsi/gameyfin/pluginapi/core/PluginConfigElement"; import Input from "Frontend/components/general/Input"; -import {PuzzlePiece} from "@phosphor-icons/react"; +import {Plug} from "@phosphor-icons/react"; interface PluginDetailsModalProps { plugin: PluginDto; @@ -52,7 +52,7 @@ export default function PluginDetailsModal({plugin, isOpen, onOpenChange}: Plugi

Details

- +

Author: {plugin.author}

Version: {plugin.version}

diff --git a/gameyfin/src/main/frontend/components/general/PluginManagementCard.tsx b/gameyfin/src/main/frontend/components/general/PluginManagementCard.tsx index 06e52cf..59400ce 100644 --- a/gameyfin/src/main/frontend/components/general/PluginManagementCard.tsx +++ b/gameyfin/src/main/frontend/components/general/PluginManagementCard.tsx @@ -1,12 +1,15 @@ -import {Card, Chip, Skeleton, useDisclosure} from "@nextui-org/react"; -import {PuzzlePiece} from "@phosphor-icons/react"; +import {Button, Card, Chip, Skeleton, Tooltip, useDisclosure} from "@nextui-org/react"; +import {Plug, Power, SlidersHorizontal} from "@phosphor-icons/react"; import {PluginManagementEndpoint} from "Frontend/generated/endpoints"; import PluginDto from "Frontend/generated/de/grimsi/gameyfin/core/plugins/management/PluginDto"; import PluginState from "Frontend/generated/org/pf4j/PluginState"; import React, {useEffect, useState} from "react"; import PluginDetailsModal from "Frontend/components/general/PluginDetailsModal"; -export function PluginManagementCard({plugin}: { plugin: PluginDto }) { +export function PluginManagementCard({plugin, updatePlugin}: { + plugin: PluginDto, + updatePlugin: (plugin: PluginDto) => void +}) { const pluginDetailsModal = useDisclosure(); const [configValid, setConfigValid] = useState(undefined); @@ -17,7 +20,12 @@ export function PluginManagementCard({plugin}: { plugin: PluginDto }) { }); }, []); + function iconColor(state: PluginState | undefined): "white" | "default" { + return "default"; + } + function borderColor(state: PluginState | undefined): "success" | "warning" | "danger" | "default" { + if (isDisabled(state)) return "warning"; if (configValid === undefined) return "default"; if (!configValid) return "danger"; return stateToColor(state); @@ -36,12 +44,46 @@ export function PluginManagementCard({plugin}: { plugin: PluginDto }) { } } + function isDisabled(state: PluginState | undefined): boolean { + return state === PluginState.DISABLED; + } + + function togglePluginEnabled() { + if (isDisabled(plugin.state)) { + PluginManagementEndpoint.enablePlugin(plugin.id).then(() => { + PluginManagementEndpoint.getPlugin(plugin.id).then((response) => { + if (response === undefined) return; + updatePlugin(response); + }); + }); + } else { + PluginManagementEndpoint.disablePlugin(plugin.id).then(() => { + PluginManagementEndpoint.getPlugin(plugin.id).then((response) => { + if (response === undefined) return; + updatePlugin(response); + }); + }); + } + } + return ( <> - + +
+ + + + + + +
- +

{plugin.name}

{plugin.version} diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/DatabasePluginStatusProvider.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/DatabasePluginStatusProvider.kt index 172731e..9f974e4 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/DatabasePluginStatusProvider.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/DatabasePluginStatusProvider.kt @@ -17,7 +17,7 @@ class DatabasePluginStatusProvider( override fun disablePlugin(pluginId: String) { val pluginManagement = pluginManagementRepository.findByIdOrNull(pluginId) if (pluginManagement != null) { - pluginManagement.enabled = true + pluginManagement.enabled = false pluginManagementRepository.save(pluginManagement) } } @@ -25,7 +25,7 @@ class DatabasePluginStatusProvider( override fun enablePlugin(pluginId: String) { val pluginManagement = pluginManagementRepository.findByIdOrNull(pluginId) if (pluginManagement != null) { - pluginManagement.enabled = false + pluginManagement.enabled = true pluginManagementRepository.save(pluginManagement) } } diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/GameyfinPluginManager.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/GameyfinPluginManager.kt index 696ae1a..2109405 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/GameyfinPluginManager.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/GameyfinPluginManager.kt @@ -22,7 +22,18 @@ class GameyfinPluginManager( // This took me way too long to figure out... // But I learned a lot about Kotlin and Java interoperability in the process init { - this.pluginStatusProvider = dbPluginStatusProvider + pluginStatusProvider = dbPluginStatusProvider + + pluginStateListeners.add { event -> + if (event is PluginStateEvent) { + log.info { "Plugin ${event.plugin.pluginId} changed state to ${event.pluginState}" } + if (event.oldState == PluginState.DISABLED) { + startPlugin(event.plugin.pluginId) + } else if (event.pluginState == PluginState.DISABLED) { + stopPlugin(event.plugin.pluginId) + } + } + } } override fun createPluginLoader(): PluginLoader { diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/PluginManagementEndpoint.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/PluginManagementEndpoint.kt index 1687578..4b26d02 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/PluginManagementEndpoint.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/PluginManagementEndpoint.kt @@ -11,6 +11,8 @@ class PluginManagementEndpoint( ) { fun getPlugins() = pluginManagementService.getPlugins() + fun getPlugin(pluginId: String) = pluginManagementService.getPlugin(pluginId) + fun startPlugin(pluginId: String) = pluginManagementService.startPlugin(pluginId) fun stopPlugin(pluginId: String) = pluginManagementService.stopPlugin(pluginId) diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/PluginManagementService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/PluginManagementService.kt index 0210dc0..b0ed58e 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/PluginManagementService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/management/PluginManagementService.kt @@ -18,6 +18,17 @@ class PluginManagementService( } } + fun getPlugin(pluginId: String): PluginDto { + val plugin = pluginManager.getPlugin(pluginId) + return PluginDto( + plugin.pluginId, + plugin.descriptor.pluginDescription, + plugin.descriptor.version, + plugin.descriptor.provider, + plugin.pluginState + ) + } + fun startPlugin(pluginId: String) { pluginManager.startPlugin(pluginId) }