feat: implement daily character guessing game with local storage and hint system

- Added character selection and history management using local storage.
- Implemented hint system that unlocks based on the number of guesses.
- Enhanced UI with animations for hint unlocks and special win conditions.
- Created a server endpoint to record wins in the database.
This commit is contained in:
2026-03-01 03:59:16 +01:00
parent 6f7bae2307
commit b8b3f8bddc
23 changed files with 2988 additions and 620 deletions

View File

@@ -1,9 +1,54 @@
{
"version": "6",
"dialect": "sqlite",
"id": "40edd98b-5a47-4a5e-a5b8-8a0f6eaaec76",
"id": "d1237d76-8f1c-4721-b8dd-d31082ed7b9a",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"arc": {
"name": "arc",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"startChapter": {
"name": "startChapter",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"endChapter": {
"name": "endChapter",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"url": {
"name": "url",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"character": {
"name": "character",
"columns": {
@@ -42,26 +87,44 @@
"notNull": false,
"autoincrement": false
},
"devilFruit": {
"name": "devilFruit",
"devilFruitId": {
"name": "devilFruitId",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"haki": {
"name": "haki",
"type": "text",
"hakiObservation": {
"name": "hakiObservation",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
"autoincrement": false,
"default": false
},
"hakiArmament": {
"name": "hakiArmament",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": false
},
"hakiConqueror": {
"name": "hakiConqueror",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": false
},
"bounty": {
"name": "bounty",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
"autoincrement": false,
"default": 0
},
"height": {
"name": "height",
@@ -79,9 +142,9 @@
},
"firstAppearance": {
"name": "firstAppearance",
"type": "text",
"type": "integer",
"primaryKey": false,
"notNull": false,
"notNull": true,
"autoincrement": false
},
"pictureUrl": {
@@ -90,16 +153,65 @@
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"epithets": {
"name": "epithets",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"arcId": {
"name": "arcId",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"url": {
"name": "url",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"isInDailyMode": {
"name": "isInDailyMode",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": true
}
},
"indexes": {},
"foreignKeys": {
"character_devilFruit_devilFruit_id_fk": {
"name": "character_devilFruit_devilFruit_id_fk",
"character_devilFruitId_devilFruit_id_fk": {
"name": "character_devilFruitId_devilFruit_id_fk",
"tableFrom": "character",
"tableTo": "devilFruit",
"columnsFrom": [
"devilFruit"
"devilFruitId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"character_arcId_arc_id_fk": {
"name": "character_arcId_arc_id_fk",
"tableFrom": "character",
"tableTo": "arc",
"columnsFrom": [
"arcId"
],
"columnsTo": [
"id"
@@ -131,11 +243,19 @@
},
"date": {
"name": "date",
"type": "integer",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"won": {
"name": "won",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": 0
},
"createdAt": {
"name": "createdAt",
"type": "integer",
@@ -171,6 +291,379 @@
"uniqueConstraints": {},
"checkConstraints": {}
},
"characterOverride": {
"name": "characterOverride",
"columns": {
"characterId": {
"name": "characterId",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"gender": {
"name": "gender",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"age": {
"name": "age",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"affiliations": {
"name": "affiliations",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"devilFruitId": {
"name": "devilFruitId",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"hakiObservation": {
"name": "hakiObservation",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"hakiArmament": {
"name": "hakiArmament",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"hakiConqueror": {
"name": "hakiConqueror",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"bounty": {
"name": "bounty",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"height": {
"name": "height",
"type": "real",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"origin": {
"name": "origin",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"firstAppearance": {
"name": "firstAppearance",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"pictureUrl": {
"name": "pictureUrl",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"epithets": {
"name": "epithets",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"arcId": {
"name": "arcId",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"url": {
"name": "url",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"notes": {
"name": "notes",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {
"characterOverride_characterId_character_id_fk": {
"name": "characterOverride_characterId_character_id_fk",
"tableFrom": "characterOverride",
"tableTo": "character",
"columnsFrom": [
"characterId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"characterOverride_devilFruitId_devilFruit_id_fk": {
"name": "characterOverride_devilFruitId_devilFruit_id_fk",
"tableFrom": "characterOverride",
"tableTo": "devilFruit",
"columnsFrom": [
"devilFruitId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"characterOverride_arcId_arc_id_fk": {
"name": "characterOverride_arcId_arc_id_fk",
"tableFrom": "characterOverride",
"tableTo": "arc",
"columnsFrom": [
"arcId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"characterScrapeValidation": {
"name": "characterScrapeValidation",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"gender": {
"name": "gender",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"age": {
"name": "age",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"affiliations": {
"name": "affiliations",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"devilFruitId": {
"name": "devilFruitId",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"hakiObservation": {
"name": "hakiObservation",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": false
},
"hakiArmament": {
"name": "hakiArmament",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": false
},
"hakiConqueror": {
"name": "hakiConqueror",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": false
},
"bounty": {
"name": "bounty",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"height": {
"name": "height",
"type": "real",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"origin": {
"name": "origin",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"firstAppearance": {
"name": "firstAppearance",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"pictureUrl": {
"name": "pictureUrl",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"epithets": {
"name": "epithets",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"arcId": {
"name": "arcId",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"url": {
"name": "url",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {
"characterScrapeValidation_devilFruitId_devilFruit_id_fk": {
"name": "characterScrapeValidation_devilFruitId_devilFruit_id_fk",
"tableFrom": "characterScrapeValidation",
"tableTo": "devilFruit",
"columnsFrom": [
"devilFruitId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"characterScrapeValidation_arcId_arc_id_fk": {
"name": "characterScrapeValidation_arcId_arc_id_fk",
"tableFrom": "characterScrapeValidation",
"tableTo": "arc",
"columnsFrom": [
"arcId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"config": {
"name": "config",
"columns": {
"key": {
"name": "key",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"devilFruit": {
"name": "devilFruit",
"columns": {
@@ -194,6 +687,13 @@
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"url": {
"name": "url",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {