diff --git a/app/package.json b/app/package.json
index 80158c5..fde9357 100644
--- a/app/package.json
+++ b/app/package.json
@@ -1,6 +1,6 @@
{
"name": "gameyfin",
- "version": "2.1.0",
+ "version": "2.1.1-preview",
"type": "module",
"dependencies": {
"@heroui/react": "2.7.9",
@@ -265,4 +265,4 @@
"disableUsageStatistics": true,
"hash": "dba97848bdace60924f9cee496353baae70cfa4fccc7bacaf827807c51908866"
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/temp/DockerHubDeprecationPopover.tsx b/app/src/main/frontend/components/temp/DockerHubDeprecationPopover.tsx
new file mode 100644
index 0000000..85cdc54
--- /dev/null
+++ b/app/src/main/frontend/components/temp/DockerHubDeprecationPopover.tsx
@@ -0,0 +1,44 @@
+import {Button, Link, Popover, PopoverContent, PopoverTrigger} from "@heroui/react";
+import {Warning} from "@phosphor-icons/react";
+
+// TODO: Remove this component before the release of version 2.2.0
+export default function DockerHubDeprecationPopover() {
+ return (
+
+
+
+
+
+
+
Image deprecation notice
+
+ Starting with version
+ 2.2.0
+ the image{' '}
+
+ grimsi/gameyfin
+
+ {' '}will no longer be published to Docker Hub.
+
+
+ Please switch to{' '}
+
+ ghcr.io/gameyfin/gameyfin
+
+ {' '}if you are currently using the Docker Hub image.
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/MainLayout.tsx b/app/src/main/frontend/views/MainLayout.tsx
index a8aa302..c7a54ee 100644
--- a/app/src/main/frontend/views/MainLayout.tsx
+++ b/app/src/main/frontend/views/MainLayout.tsx
@@ -14,6 +14,7 @@ import {useSnapshot} from "valtio/react";
import {gameState} from "Frontend/state/GameState";
import ScanProgressPopover from "Frontend/components/general/ScanProgressPopover";
import {isAdmin} from "Frontend/util/utils";
+import DockerHubDeprecationPopover from "Frontend/components/temp/DockerHubDeprecationPopover";
export default function MainLayout() {
const navigate = useNavigate();
@@ -105,13 +106,22 @@ export default function MainLayout() {
{isAdmin(auth) &&
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
{auth.state.user &&
diff --git a/app/src/main/frontend/views/SetupView.tsx b/app/src/main/frontend/views/SetupView.tsx
index 38d9a4c..1d54e5d 100644
--- a/app/src/main/frontend/views/SetupView.tsx
+++ b/app/src/main/frontend/views/SetupView.tsx
@@ -85,17 +85,26 @@ function SetupView() {
initialValues={{username: '', email: '', password: '', passwordRepeat: ''}}
onSubmit={
async (values: any) => {
- await SetupEndpoint.registerSuperAdmin({
- username: values.username,
- password: values.password,
- email: values.email
- });
- addToast({
- title: "Setup finished",
- description: "Have fun with Gameyfin!",
- color: "success"
- })
- navigate('/login');
+ try {
+ await SetupEndpoint.registerSuperAdmin({
+ username: values.username,
+ password: values.password,
+ email: values.email
+ });
+ addToast({
+ title: "Setup finished",
+ description: "Have fun with Gameyfin!",
+ color: "success"
+ });
+ } catch (e) {
+ addToast({
+ title: "Could not register super admin user",
+ description: "Maybe Gameyfin is already set up?",
+ color: "warning"
+ });
+ } finally {
+ navigate('/login');
+ }
}
}
>
diff --git a/app/src/main/kotlin/org/gameyfin/app/requests/GameRequestService.kt b/app/src/main/kotlin/org/gameyfin/app/requests/GameRequestService.kt
index 3f81d65..5676e3f 100644
--- a/app/src/main/kotlin/org/gameyfin/app/requests/GameRequestService.kt
+++ b/app/src/main/kotlin/org/gameyfin/app/requests/GameRequestService.kt
@@ -102,7 +102,7 @@ class GameRequestService(
listOf(GameRequestStatus.PENDING)
)
val maxRequestsPerUser = config.get(ConfigProperties.Requests.Games.MaxOpenRequestsPerUser) ?: 0
- if (maxRequestsPerUser == 0 || (auth?.isAdmin() != true && pendingRequestsForUser.size >= maxRequestsPerUser)) {
+ if (maxRequestsPerUser != 0 && auth?.isAdmin() != true && pendingRequestsForUser.size >= maxRequestsPerUser) {
throw EndpointException("You have reached the maximum number of pending requests (${maxRequestsPerUser})")
}
diff --git a/app/src/main/resources/db/migration/V2.1.1__Recreate_game_image_fks_without_unique_indexes.sql b/app/src/main/resources/db/migration/V2.1.1__Recreate_game_image_fks_without_unique_indexes.sql
new file mode 100644
index 0000000..158bdeb
--- /dev/null
+++ b/app/src/main/resources/db/migration/V2.1.1__Recreate_game_image_fks_without_unique_indexes.sql
@@ -0,0 +1,70 @@
+-- Flyway Migration: V2.1.1
+-- Purpose: Fully eliminate unintended uniqueness on GAME.COVER_IMAGE_ID / HEADER_IMAGE_ID
+-- by dropping and recreating foreign keys and removing lingering unique indexes
+-- Context:
+-- * Original schema created UNIQUE constraints (UK52... cover, UK30... header).
+-- * V2.1.0.1 dropped those constraints but H2 left behind unique indexes (UK52..._INDEX_n etc.).
+-- Strategy:
+-- 1. Drop the foreign keys (idempotent).
+-- 2. Drop any remaining unique constraints (defensive repeat) and their indexes.
+-- 3. Recreate NON-UNIQUE supporting indexes explicitly (optional but good for lookups).
+-- 4. Recreate the foreign keys cleanly without reintroducing uniqueness.
+-- 5. All steps are idempotent / tolerant so reruns don't fail.
+
+/******************************************************************************************
+ * 1. Drop foreign keys so their backing indexes can be dropped safely
+ ******************************************************************************************/
+ALTER TABLE GAME
+ DROP CONSTRAINT IF EXISTS FK_GAME_COVER_IMAGE;
+ALTER TABLE GAME
+ DROP CONSTRAINT IF EXISTS FK_GAME_HEADER_IMAGE;
+
+-- Also attempt legacy hashed names (in case rename earlier never ran)
+ALTER TABLE GAME
+ DROP CONSTRAINT IF EXISTS FK6CVB43REAYSNYPI0XDY6HQTVF; -- old cover FK
+ALTER TABLE GAME
+ DROP CONSTRAINT IF EXISTS FK8N86NDPGKMOO7YOLX6HL8N84G;
+-- old header FK
+
+/******************************************************************************************
+ * 2. Drop any lingering UNIQUE constraints again (defensive) and their indexes
+ ******************************************************************************************/
+ALTER TABLE GAME
+ DROP CONSTRAINT IF EXISTS UK52RQ62FLPBNTI77BYKM7UAHKQ; -- old unique cover
+ALTER TABLE GAME
+ DROP CONSTRAINT IF EXISTS UK30B16LLQV54H40XIOGP7T9P35; -- old unique header
+ALTER TABLE GAME
+ DROP CONSTRAINT IF EXISTS UQ_GAME_COVER_IMAGE_ID; -- friendly (future) name
+ALTER TABLE GAME
+ DROP CONSTRAINT IF EXISTS UQ_GAME_HEADER_IMAGE_ID;
+-- friendly (future) name
+
+-- Drop possible leftover unique indexes (multiple variants tried)
+DROP INDEX IF EXISTS UK52RQ62FLPBNTI77BYKM7UAHKQ_INDEX_2;
+DROP INDEX IF EXISTS UK52RQ62FLPBNTI77BYKM7UAHKQ_INDEX_1;
+DROP INDEX IF EXISTS UK30B16LLQV54H40XIOGP7T9P35_INDEX_2;
+DROP INDEX IF EXISTS UK30B16LLQV54H40XIOGP7T9P35_INDEX_1;
+
+/******************************************************************************************
+ * 3. Create explicit NON-UNIQUE indexes (only if missing)
+ ******************************************************************************************/
+CREATE INDEX IF NOT EXISTS IDX_GAME_COVER_IMAGE ON GAME (COVER_IMAGE_ID);
+CREATE INDEX IF NOT EXISTS IDX_GAME_HEADER_IMAGE ON GAME (HEADER_IMAGE_ID);
+
+/******************************************************************************************
+ * 4. Recreate foreign keys (non-unique by definition)
+ ******************************************************************************************/
+ALTER TABLE GAME
+ ADD CONSTRAINT FK_GAME_COVER_IMAGE FOREIGN KEY (COVER_IMAGE_ID) REFERENCES IMAGE (ID);
+ALTER TABLE GAME
+ ADD CONSTRAINT FK_GAME_HEADER_IMAGE FOREIGN KEY (HEADER_IMAGE_ID) REFERENCES IMAGE (ID);
+
+/******************************************************************************************
+ * 5. (Optional manual verification after migration)
+ * -- SELECT INDEX_NAME, NON_UNIQUE, COLUMN_NAME FROM INFORMATION_SCHEMA.INDEXES
+ * -- WHERE TABLE_NAME='GAME' AND COLUMN_NAME IN ('COVER_IMAGE_ID','HEADER_IMAGE_ID');
+ * Expected: ONLY non-unique indexes (NON_UNIQUE=TRUE) for those columns.
+ ******************************************************************************************/
+
+-- End of migration.
+
diff --git a/build.gradle.kts b/build.gradle.kts
index 665b0e0..8da615d 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -6,7 +6,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
import java.nio.file.Files
group = "org.gameyfin"
-version = "2.1.0"
+version = "2.1.1-preview"
allprojects {
repositories {