// RSE display component for ai.syui.rse.user collection import { renderCard, type UserCard, type CardAdminEntry, type CardAdminData } from './card' export interface RseAdminItem { id: number name: string text: { ja: string; en: string } } export interface RseAdminData { item: RseAdminItem[] } export interface RseItem { id: number cp: number mode: number unique: boolean } export interface RseCollection { item: RseItem[] character: RseItem[] createdAt: string updatedAt: string } // Get current language function getLang(): string { return localStorage.getItem('preferredLang') || 'ja' } // Get localized text function getLocalizedText(obj: { ja: string; en: string } | undefined): string { if (!obj) return '' const lang = getLang() return obj[lang as 'ja' | 'en'] || obj.ja || obj.en || '' } // Get rarity class from unique flag function getRarityClass(item: RseItem): string { if (item.unique) return 'unique' return '' } // Get cards for a character (character 0 = cards 0-99, character 1 = cards 100-199, etc.) function getCardsForCharacter( characterId: number, userCards: UserCard[], adminData: CardAdminData | null ): { card: UserCard; adminEntry?: CardAdminEntry }[] { const minId = characterId * 100 const maxId = minId + 99 // Build admin lookup map const adminMap = new Map() if (adminData?.card) { for (const entry of adminData.card) { adminMap.set(entry.id, entry) } } // Filter and dedupe cards for this character const cardGroups = new Map() for (const card of userCards) { if (card.id >= minId && card.id <= maxId) { const existing = cardGroups.get(card.id) if (!existing || card.cp > existing.cp || card.unique) { cardGroups.set(card.id, card) } } } // Sort by ID and add admin entries return Array.from(cardGroups.values()) .sort((a, b) => a.id - b.id) .map(card => ({ card, adminEntry: adminMap.get(card.id) })) } // Render character section with its cards below function renderCharacterSection( item: RseItem, userCards: UserCard[], adminData: CardAdminData | null ): string { const rarityClass = getRarityClass(item) const effectsHtml = rarityClass ? `
` : '' // Get cards for this character const characterCards = getCardsForCharacter(item.id, userCards, adminData) const cardsHtml = characterCards.map(({ card, adminEntry }) => renderCard(card, '/card', undefined, adminEntry) ).join('') return `
character ${item.id}
${effectsHtml}
${item.cp}
${characterCards.length > 0 ? `
${cardsHtml}
` : ''}
` } // Render single item function renderRseItem(item: RseItem, rseAdminData: RseAdminData | null): string { const rarityClass = getRarityClass(item) const effectsHtml = rarityClass ? `
` : '' // Get admin entry for this item const adminEntry = rseAdminData?.item?.find(i => i.id === item.id) const name = adminEntry?.name || '' const text = adminEntry ? getLocalizedText(adminEntry.text) : '' const infoHtml = (name || text) ? `
${name}
${text ? `
${text}
` : ''}
` : '' return `
item ${item.id}
${effectsHtml}
${item.cp}
${infoHtml}
` } // Render RSE page export function renderRsePage( collection: RseCollection | null, handle: string, userCards: UserCard[] = [], adminData: CardAdminData | null = null, rseAdminData: RseAdminData | null = null ): string { const jsonUrl = `/@${handle}/at/collection/ai.syui.rse.user/self` if (!collection) { return `

RSE

json

No RSE data found for @${handle}

` } const characters = collection.character || [] const items = collection.item || [] // Stats const totalChars = characters.length const totalItems = items.length const uniqueChars = characters.filter(c => c.unique).length // Sort by id const sortedChars = [...characters].sort((a, b) => a.id - b.id) const sortedItems = [...items].sort((a, b) => a.id - b.id) const charsHtml = sortedChars.map(c => renderCharacterSection(c, userCards, adminData) ).join('') const itemsHtml = sortedItems.map(i => renderRseItem(i, rseAdminData)).join('') return `
${totalChars} Characters
${totalItems} Items
${uniqueChars} Unique
${charsHtml ? `

Characters

${charsHtml}
` : ''} ${itemsHtml ? `

Items

${itemsHtml}
` : ''}
` }