Expand character model with additional attributes and advanced customization options
- Added fields such as `nickname`, `age`, `gender`, `species`, `nationality`, `status`, and others to enhance character customization. - Modified localization files to include new field labels and placeholders. - Updated `CharacterComponent` and `CharacterDetail` components with UI elements for the newly added attributes. - Introduced "Advanced Mode" toggle to manage visibility of extended customization options. - Refactored database models and repository methods (`addNewCharacter`, `updateCharacter`, and `fetchCharacters`) to handle the extended schema. - Improved data encryption and decryption workflows for secure storage of added attributes. - Enhanced user experience by reorganizing character customization layouts.
This commit is contained in:
@@ -7,12 +7,23 @@ export interface BookCharactersTable extends Record<string, SQLiteValue> {
|
||||
user_id: string;
|
||||
first_name: string;
|
||||
last_name: string | null;
|
||||
nickname: string | null;
|
||||
age: string | null;
|
||||
gender: string | null;
|
||||
species: string | null;
|
||||
nationality: string | null;
|
||||
status: string | null;
|
||||
category: string;
|
||||
title: string | null;
|
||||
image: string | null;
|
||||
role: string | null;
|
||||
biography: string | null;
|
||||
history: string | null;
|
||||
speech_pattern: string | null;
|
||||
catchphrase: string | null;
|
||||
residence: string | null;
|
||||
notes: string | null;
|
||||
color: string | null;
|
||||
last_update: number;
|
||||
}
|
||||
|
||||
@@ -43,12 +54,23 @@ export interface CharacterResult extends Record<string, SQLiteValue> {
|
||||
character_id: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
nickname: string;
|
||||
age: string;
|
||||
gender: string;
|
||||
species: string;
|
||||
nationality: string;
|
||||
status: string;
|
||||
title: string;
|
||||
category: string;
|
||||
image: string;
|
||||
role: string;
|
||||
biography: string;
|
||||
history: string;
|
||||
speech_pattern: string;
|
||||
catchphrase: string;
|
||||
residence: string;
|
||||
notes: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export interface AttributeResult extends Record<string, SQLiteValue> {
|
||||
@@ -81,7 +103,7 @@ export default class CharacterRepo {
|
||||
public static fetchCharacters(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): CharacterResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT character_id, first_name, last_name, title, category, image, role, biography, history FROM book_characters WHERE book_id=? AND user_id=?';
|
||||
const query: string = 'SELECT character_id, first_name, last_name, nickname, age, gender, species, nationality, status, title, category, image, role, biography, history, speech_pattern, catchphrase, residence, notes, color FROM book_characters WHERE book_id=? AND user_id=?';
|
||||
const params: SQLiteValue[] = [bookId, userId];
|
||||
const characters: CharacterResult[] = db.all(query, params) as CharacterResult[];
|
||||
return characters;
|
||||
@@ -100,23 +122,48 @@ export default class CharacterRepo {
|
||||
* Adds a new character to the database.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param characterId - The unique identifier for the new character
|
||||
* @param encryptedName - The encrypted first name of the character
|
||||
* @param encryptedLastName - The encrypted last name of the character
|
||||
* @param encryptedTitle - The encrypted title of the character
|
||||
* @param encryptedCategory - The encrypted category of the character
|
||||
* @param encryptedImage - The encrypted image path of the character
|
||||
* @param encryptedRole - The encrypted role of the character
|
||||
* @param encryptedBiography - The encrypted biography of the character
|
||||
* @param encryptedHistory - The encrypted history of the character
|
||||
* @param characterData - Object containing all encrypted character fields
|
||||
* @param bookId - The unique identifier of the book
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns The character ID if successful
|
||||
*/
|
||||
public static addNewCharacter(userId: string, characterId: string, encryptedName: string, encryptedLastName: string, encryptedTitle: string, encryptedCategory: string, encryptedImage: string, encryptedRole: string, encryptedBiography: string, encryptedHistory: string, bookId: string, lang: 'fr' | 'en' = 'fr'): string {
|
||||
public static addNewCharacter(userId: string, characterId: string, characterData: {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
nickname: string;
|
||||
age: string;
|
||||
gender: string;
|
||||
species: string;
|
||||
nationality: string;
|
||||
status: string;
|
||||
title: string;
|
||||
category: string;
|
||||
image: string;
|
||||
role: string;
|
||||
biography: string;
|
||||
history: string;
|
||||
speechPattern: string;
|
||||
catchphrase: string;
|
||||
residence: string;
|
||||
notes: string;
|
||||
color: string;
|
||||
}, bookId: string, lang: 'fr' | 'en' = 'fr'): string {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'INSERT INTO `book_characters` (character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)';
|
||||
const params: SQLiteValue[] = [characterId, bookId, userId, encryptedName, encryptedLastName, encryptedCategory, encryptedTitle, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, System.timeStampInSeconds()];
|
||||
const query: string = `INSERT INTO book_characters (
|
||||
character_id, book_id, user_id, first_name, last_name, nickname, age, gender, species, nationality, status,
|
||||
category, title, image, role, biography, history, speech_pattern, catchphrase, residence, notes, color, last_update
|
||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`;
|
||||
const params: SQLiteValue[] = [
|
||||
characterId, bookId, userId,
|
||||
characterData.firstName, characterData.lastName, characterData.nickname,
|
||||
characterData.age, characterData.gender, characterData.species,
|
||||
characterData.nationality, characterData.status, characterData.category,
|
||||
characterData.title, characterData.image, characterData.role,
|
||||
characterData.biography, characterData.history, characterData.speechPattern,
|
||||
characterData.catchphrase, characterData.residence, characterData.notes,
|
||||
characterData.color, System.timeStampInSeconds()
|
||||
];
|
||||
const insertResult: RunResult = db.run(query, params);
|
||||
if (!insertResult || insertResult.changes === 0) {
|
||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout du personnage.` : `Error adding character.`);
|
||||
@@ -168,23 +215,48 @@ export default class CharacterRepo {
|
||||
* Updates an existing character's information.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param id - The unique identifier of the character to update
|
||||
* @param encryptedName - The encrypted first name of the character
|
||||
* @param encryptedLastName - The encrypted last name of the character
|
||||
* @param encryptedTitle - The encrypted title of the character
|
||||
* @param encryptedCategory - The encrypted category of the character
|
||||
* @param encryptedImage - The encrypted image path of the character
|
||||
* @param encryptedRole - The encrypted role of the character
|
||||
* @param encryptedBiography - The encrypted biography of the character
|
||||
* @param encryptedHistory - The encrypted history of the character
|
||||
* @param characterData - Object containing all encrypted character fields
|
||||
* @param lastUpdate - The timestamp of the last update
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the update was successful, false otherwise
|
||||
*/
|
||||
static updateCharacter(userId: string, id: string, encryptedName: string, encryptedLastName: string, encryptedTitle: string, encryptedCategory: string, encryptedImage: string, encryptedRole: string, encryptedBiography: string, encryptedHistory: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
static updateCharacter(userId: string, id: string, characterData: {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
nickname: string;
|
||||
age: string;
|
||||
gender: string;
|
||||
species: string;
|
||||
nationality: string;
|
||||
status: string;
|
||||
title: string;
|
||||
category: string;
|
||||
image: string;
|
||||
role: string;
|
||||
biography: string;
|
||||
history: string;
|
||||
speechPattern: string;
|
||||
catchphrase: string;
|
||||
residence: string;
|
||||
notes: string;
|
||||
color: string;
|
||||
}, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE `book_characters` SET `first_name`=?,`last_name`=?,`title`=?,`category`=?,`image`=?,`role`=?,`biography`=?,`history`=?,`last_update`=? WHERE `character_id`=? AND `user_id`=?';
|
||||
const params: SQLiteValue[] = [encryptedName, encryptedLastName, encryptedTitle, encryptedCategory, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, lastUpdate, id, userId];
|
||||
const query: string = `UPDATE book_characters SET
|
||||
first_name=?, last_name=?, nickname=?, age=?, gender=?, species=?, nationality=?, status=?,
|
||||
title=?, category=?, image=?, role=?, biography=?, history=?,
|
||||
speech_pattern=?, catchphrase=?, residence=?, notes=?, color=?, last_update=?
|
||||
WHERE character_id=? AND user_id=?`;
|
||||
const params: SQLiteValue[] = [
|
||||
characterData.firstName, characterData.lastName, characterData.nickname,
|
||||
characterData.age, characterData.gender, characterData.species,
|
||||
characterData.nationality, characterData.status, characterData.title,
|
||||
characterData.category, characterData.image, characterData.role,
|
||||
characterData.biography, characterData.history, characterData.speechPattern,
|
||||
characterData.catchphrase, characterData.residence, characterData.notes,
|
||||
characterData.color, lastUpdate, id, userId
|
||||
];
|
||||
const updateResult: RunResult = db.run(query, params);
|
||||
return updateResult.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
@@ -396,7 +468,9 @@ export default class CharacterRepo {
|
||||
static async fetchBookCharacters(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookCharactersTable[]> {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update FROM book_characters WHERE user_id=? AND book_id=?';
|
||||
const query: string = `SELECT character_id, book_id, user_id, first_name, last_name, nickname, age, gender, species, nationality, status,
|
||||
category, title, image, role, biography, history, speech_pattern, catchphrase, residence, notes, color, last_update
|
||||
FROM book_characters WHERE user_id=? AND book_id=?`;
|
||||
const params: SQLiteValue[] = [userId, bookId];
|
||||
const characters: BookCharactersTable[] = db.all(query, params) as BookCharactersTable[];
|
||||
return characters;
|
||||
@@ -487,24 +561,48 @@ export default class CharacterRepo {
|
||||
* @param characterId - The unique identifier of the character
|
||||
* @param bookId - The unique identifier of the book
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param firstName - The first name of the character
|
||||
* @param lastName - The last name of the character (nullable)
|
||||
* @param category - The category of the character
|
||||
* @param title - The title of the character (nullable)
|
||||
* @param image - The image path of the character (nullable)
|
||||
* @param role - The role of the character (nullable)
|
||||
* @param biography - The biography of the character (nullable)
|
||||
* @param history - The history of the character (nullable)
|
||||
* @param characterData - Object containing all character fields
|
||||
* @param lastUpdate - The timestamp of the last update
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the insertion was successful, false otherwise
|
||||
*/
|
||||
static insertSyncCharacter(characterId: string, bookId: string, userId: string, firstName: string, lastName: string | null, category: string, title: string | null, image: string | null, role: string | null, biography: string | null, history: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||
static insertSyncCharacter(characterId: string, bookId: string, userId: string, characterData: {
|
||||
firstName: string;
|
||||
lastName: string | null;
|
||||
nickname: string | null;
|
||||
age: string | null;
|
||||
gender: string | null;
|
||||
species: string | null;
|
||||
nationality: string | null;
|
||||
status: string | null;
|
||||
category: string;
|
||||
title: string | null;
|
||||
image: string | null;
|
||||
role: string | null;
|
||||
biography: string | null;
|
||||
history: string | null;
|
||||
speechPattern: string | null;
|
||||
catchphrase: string | null;
|
||||
residence: string | null;
|
||||
notes: string | null;
|
||||
color: string | null;
|
||||
}, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `INSERT INTO book_characters (character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
||||
const params: SQLiteValue[] = [characterId, bookId, userId, firstName, lastName, category, title, image, role, biography, history, lastUpdate];
|
||||
const query: string = `INSERT INTO book_characters (
|
||||
character_id, book_id, user_id, first_name, last_name, nickname, age, gender, species, nationality, status,
|
||||
category, title, image, role, biography, history, speech_pattern, catchphrase, residence, notes, color, last_update
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
||||
const params: SQLiteValue[] = [
|
||||
characterId, bookId, userId,
|
||||
characterData.firstName, characterData.lastName, characterData.nickname,
|
||||
characterData.age, characterData.gender, characterData.species,
|
||||
characterData.nationality, characterData.status, characterData.category,
|
||||
characterData.title, characterData.image, characterData.role,
|
||||
characterData.biography, characterData.history, characterData.speechPattern,
|
||||
characterData.catchphrase, characterData.residence, characterData.notes,
|
||||
characterData.color, lastUpdate
|
||||
];
|
||||
const insertResult: RunResult = db.run(query, params);
|
||||
return insertResult.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
@@ -555,7 +653,8 @@ export default class CharacterRepo {
|
||||
static async fetchCompleteCharacterById(id: string, lang: "fr" | "en"): Promise<BookCharactersTable[]> {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `SELECT character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update
|
||||
const query: string = `SELECT character_id, book_id, user_id, first_name, last_name, nickname, age, gender, species, nationality, status,
|
||||
category, title, image, role, biography, history, speech_pattern, catchphrase, residence, notes, color, last_update
|
||||
FROM book_characters
|
||||
WHERE character_id = ?`;
|
||||
const params: SQLiteValue[] = [id];
|
||||
|
||||
Reference in New Issue
Block a user