Refactor character affiliations to singular form

- Updated character data structure to replace 'affiliations' and 'frAffiliations' with 'affiliation' and 'frAffiliation'.
- Modified related functions and components to accommodate the new structure.
- Adjusted database schema and server-side logic to reflect the changes in character affiliation handling.
- Ensured all references in the UI components and data import/export scripts are updated accordingly.
This commit is contained in:
2026-04-14 21:56:26 +02:00
parent fa14156d82
commit d75c74ac3c
12 changed files with 1256 additions and 107 deletions

View File

@@ -8,7 +8,7 @@
export let columnVisibility: {
status?: boolean;
gender?: boolean;
affiliations?: boolean;
affiliation?: boolean;
devilFruitType?: boolean;
haki?: boolean;
bounty?: boolean;
@@ -18,52 +18,6 @@
arc?: boolean;
};
function normalizeAffiliations(value: unknown): string[] {
if (Array.isArray(value)) {
return value
.map((entry) => (typeof entry === 'string' ? entry.trim() : ''))
.filter((entry) => entry.length > 0);
}
if (typeof value === 'string') {
const trimmed = value.trim();
if (trimmed.length === 0) {
return [];
}
if (trimmed.startsWith('[')) {
try {
const parsed = JSON.parse(trimmed);
if (Array.isArray(parsed)) {
return parsed
.map((entry) => (typeof entry === 'string' ? entry.trim() : ''))
.filter((entry) => entry.length > 0);
}
} catch {
return [];
}
}
return trimmed
.split(',')
.map((entry) => entry.trim())
.filter((entry) => entry.length > 0);
}
return [];
}
function firstAffiliation(value: unknown): string | null {
const affiliations = normalizeAffiliations(value);
return affiliations.length > 0 ? affiliations[0] : null;
}
function hasMatchingPrimaryAffiliation(characterAffiliations: unknown, dailyAffiliations: unknown): boolean {
const characterPrimary = firstAffiliation(characterAffiliations);
const dailyPrimary = firstAffiliation(dailyAffiliations);
return characterPrimary === dailyPrimary;
}
$: isFrench = $language === 'fr';
function getDisplayName(character: CharacterWithRelations): string {
@@ -106,6 +60,14 @@
return character.arcName;
}
function getDislayAffiliation(character: CharacterWithRelations): string | null {
if (isFrench && typeof character.frAffiliation === 'string' && character.frAffiliation.length > 0) {
return character.frAffiliation;
}
return character.affiliation;
}
function hasMatchingArc(characterEntry: CharacterWithRelations, dailyEntry: CharacterWithRelations): boolean {
return getDisplayArcName(characterEntry) === getDisplayArcName(dailyEntry);
}
@@ -156,7 +118,7 @@
</p>
</div>
{/if}
{#if columnVisibility.affiliations !== false}
{#if columnVisibility.affiliation !== false}
<div
class="flex w-16 shrink-0 items-center justify-center rounded-lg border border-amber-200/30 bg-amber-900/30 p-1 text-center sm:w-20 sm:p-2 md:w-24"
>
@@ -319,23 +281,15 @@
{/if}
<!-- Affiliations -->
{#if columnVisibility.affiliations !== false}
{#if columnVisibility.affiliation !== false}
<div
class="h-16 w-16 shrink-0 rounded-lg border border-white/10 sm:h-20 sm:w-20 md:h-24 md:w-24 {hasMatchingPrimaryAffiliation(character.affiliations, dailyCharacter.affiliations)
class="h-16 w-16 shrink-0 rounded-lg border border-white/10 sm:h-20 sm:w-20 md:h-24 md:w-24 {getDislayAffiliation(character) === getDislayAffiliation(dailyCharacter)
? 'bg-emerald-600/90'
: 'bg-red-900/60'} flex items-center justify-center overflow-hidden p-1 sm:p-2"
: 'bg-red-900/60'} flex items-center justify-center p-1 sm:p-2"
>
{#if firstAffiliation(character.affiliations)}
<p
class="w-full text-center text-[10px] leading-tight font-bold wrap-break-word whitespace-normal text-white sm:text-xs md:text-sm"
>
{firstAffiliation(character.affiliations)}
</p>
{:else}
<p class="text-center text-xs font-bold text-slate-400 sm:text-sm md:text-base">
-
</p>
{/if}
<p class="text-center text-[10px] font-bold text-white sm:text-xs md:text-sm">
{getDislayAffiliation(character) || $t.game.components.guessHistory.unknown}
</p>
</div>
{/if}