5180 fichiers 38.5 Mo 0 téléchargements 459 vues mis à jour il y a 7 heures ui
nitro-v36-with-renderer-v36 / src / components / inventory / views / prefix / InventoryPrefixView.tsx
InventoryPrefixView.tsx 13.2 Ko Télécharger le fichier
import { CreateLinkEvent } from '@octane/renderer';
import { FC, useEffect, useMemo, useState } from 'react';
import { getPrefixEffectStyle, getPrefixFontStyle, IPrefixItem, localizeWithFallback, LocalizeText, parsePrefixColors } from '../../../../api';
import { GetNickIconUrl } from '../../../../assets/images/user_custom/nick_icons';
import { ClassicScrollAreaView } from '../../../../common/scroll-area/ClassicScrollAreaView';
import { useInventoryNickIcons, useInventoryPrefixes, useNotification } from '../../../../hooks';
import { OctaneButton } from '../../../../layout';
import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
import { TabBar, TabBarTab } from '../../../../common/TabBar';
import { BaseButton } from '../../../../common/BaseButton';
import { NativeTextTree } from '../../../../common/native-text/NativeTextTree';

type InventoryIdentityTab = 'prefixes' | 'icons';

const PrefixPreview: FC<{ text: string; color: string; icon: string; effect?: string; font?: string; className?: string }> = ({
    text,
    color,
    icon,
    effect = '',
    font = '',
    className = ''
}) => {
    const colors = parsePrefixColors(text, color);
    const hasMultiColor = colors.length > 1 && new Set(colors).size > 1;
    const fxStyle = getPrefixEffectStyle(effect, colors[0] || '#FFFFFF');
    const fontStyle = getPrefixFontStyle(font);

    return (
        <NativeTextTree>
            <span className={`octane-inventory-prefix-text ${className}`} style={{ ...fontStyle, ...fxStyle }}>
                {icon && <span className="octane-inventory-prefix-icon">{icon}</span>}
                <span style={hasMultiColor ? { ...fontStyle, ...fxStyle } : { ...fontStyle, ...fxStyle, color: colors[0] || '#FFFFFF' }}>
                    {'{'}
                    {hasMultiColor
                        ? [...text].map((char, i) => (
                              <span key={i} style={{ ...fontStyle, color: colors[i] || colors[colors.length - 1], ...getPrefixEffectStyle(effect, colors[i]) }}>
                                  {char}
                              </span>
                          ))
                        : text}
                    {'}'}
                </span>
            </span>
        </NativeTextTree>
    );
};

const cellClass = (isSelected: boolean, isActive: boolean) =>
    `octane-inventory-identity-cell${isSelected ? ' is-selected' : ''}${isActive ? ' is-active' : ''}`;

export const InventoryPrefixView: FC<{}> = () => {
    const [isVisible, setIsVisible] = useState(false);
    const [activeTab, setActiveTab] = useState<InventoryIdentityTab>('prefixes');
    const {
        prefixes = [],
        activePrefix = null,
        selectedPrefix = null,
        setSelectedPrefix = null,
        activatePrefix = null,
        deactivatePrefix = null,
        deletePrefix = null,
        activate = null,
        deactivate = null
    } = useInventoryPrefixes();
    const {
        nickIcons = [],
        activeNickIcon = null,
        selectedNickIcon = null,
        setSelectedNickIcon = null,
        activateNickIcon = null,
        deactivateNickIcon = null,
        activate: activateNickIcons = null,
        deactivate: deactivateNickIcons = null
    } = useInventoryNickIcons();
    const { showConfirm = null } = useNotification();
    const selectedIconUrl = useMemo(() => (selectedNickIcon ? GetNickIconUrl(selectedNickIcon.iconKey) : ''), [selectedNickIcon]);

    const attemptDeletePrefix = () => {
        if (!selectedPrefix) return;

        showConfirm(
            localizeWithFallback('inventory.prefixes.delete.confirm', 'Are you sure you want to delete the prefix ${prefix}?', ['prefix'], [`{${selectedPrefix.text}}`]),
            () => deletePrefix(selectedPrefix.id),
            null,
            null,
            null,
            LocalizeText('inventory.delete.confirm_delete.title')
        );
    };

    useEffect(() => {
        if (!isVisible) return;

        const prefixVisibilityId = activate();
        const iconVisibilityId = activateNickIcons();

        return () => {
            deactivate(prefixVisibilityId);
            deactivateNickIcons(iconVisibilityId);
        };
    }, [isVisible, activate, activateNickIcons, deactivate, deactivateNickIcons]);

    useEffect(() => {
        setIsVisible(true);

        return () => setIsVisible(false);
    }, []);

    const tabs: { id: InventoryIdentityTab; label: string }[] = [
        { id: 'prefixes', label: localizeWithFallback('inventory.prefixes.tab.prefixes', 'Prefixes') },
        { id: 'icons', label: localizeWithFallback('inventory.prefixes.tab.icons', 'Icons') }
    ];

    const activeLabel = localizeWithFallback('inventory.prefixes.active', 'Active');
    const activateLabel = localizeWithFallback('inventory.prefixes.activate', 'Activate');
    const deactivateLabel = localizeWithFallback('inventory.prefixes.deactivate', 'Deactivate');
    const deleteLabel = localizeWithFallback('inventory.prefixes.delete', 'Delete');

    return (
        <NativeTextTree>
            <div className="octane-inventory-identity">
                <TabBar className="octane-inventory-identity-tabs" value={activeTab}>
                    {tabs.map((tab) => (
                        <TabBarTab
                            key={tab.id}
                            className={`octane-inventory-identity-tab${activeTab === tab.id ? ' is-active' : ''}`}
                            value={tab.id}
                            onClick={() => setActiveTab(tab.id)}
                        >
                            {tab.label}
                        </TabBarTab>
                    ))}
                </TabBar>

                {activeTab === 'prefixes' &&
                    (prefixes.length === 0 ? (
                        <InventoryCategoryEmptyView
                            desc={localizeWithFallback('inventory.empty.prefixes.desc', 'Prefixes you buy show up here.')}
                            title={localizeWithFallback('inventory.empty.prefixes.title', 'You have no prefixes')}
                        />
                    ) : (
                        <div className="octane-inventory-animals is-prefixes">
                            <div className="octane-inventory-animal-grid">
                                <ClassicScrollAreaView className="size-full">
                                    <div className="octane-inventory-animal-cells">
                                        {prefixes.map((prefix: IPrefixItem) => (
                                            <BaseButton
                                                key={prefix.id}
                                                className={cellClass(selectedPrefix?.id === prefix.id, !!prefix.active)}
                                                type="button"
                                                onClick={() => setSelectedPrefix(prefix)}
                                            >
                                                <PrefixPreview color={prefix.color} effect={prefix.effect} font={prefix.font} icon={prefix.icon} text={prefix.text} />
                                            </BaseButton>
                                        ))}
                                    </div>
                                </ClassicScrollAreaView>
                            </div>
                            <div className="octane-inventory-animal-preview">
                                <div className="octane-inventory-animal-name">{selectedPrefix?.active ? activeLabel : ''}</div>
                                <div className="octane-inventory-animal-image">
                                    {selectedPrefix && (
                                        <PrefixPreview
                                            className="is-large"
                                            color={selectedPrefix.color}
                                            effect={selectedPrefix.effect}
                                            font={selectedPrefix.font}
                                            icon={selectedPrefix.icon}
                                            text={selectedPrefix.text}
                                        />
                                    )}
                                </div>
                                <div className="octane-inventory-animal-description">
                                    {!selectedPrefix && activePrefix && (
                                        <>
                                            {activeLabel}: <PrefixPreview color={activePrefix.color} effect={activePrefix.effect} font={activePrefix.font} icon={activePrefix.icon} text={activePrefix.text} />
                                        </>
                                    )}
                                </div>
                                <div className="octane-inventory-animal-actions">
                                    <OctaneButton
                                        className="octane-inventory-animal-place"
                                        disabled={!selectedPrefix}
                                        onClick={() => (selectedPrefix.active ? deactivatePrefix() : activatePrefix(selectedPrefix.id))}
                                    >
                                        {selectedPrefix?.active ? deactivateLabel : activateLabel}
                                    </OctaneButton>
                                    <OctaneButton className="octane-inventory-animal-place" disabled={!selectedPrefix || selectedPrefix.active} onClick={attemptDeletePrefix}>
                                        {deleteLabel}
                                    </OctaneButton>
                                </div>
                            </div>
                        </div>
                    ))}

                {activeTab === 'icons' &&
                    (nickIcons.length === 0 ? (
                        <InventoryCategoryEmptyView
                            actionLabel={localizeWithFallback('inventory.empty.nickicons.action', 'Customize identity')}
                            desc={localizeWithFallback('inventory.empty.nickicons.desc', 'Icons are bought in the identity customizer.')}
                            onAction={() => CreateLinkEvent('customize/show')}
                            title={localizeWithFallback('inventory.empty.nickicons.title', 'You have no icons')}
                        />
                    ) : (
                        <div className="octane-inventory-animals is-prefixes">
                            <div className="octane-inventory-animal-grid">
                                <ClassicScrollAreaView className="size-full">
                                    <div className="octane-inventory-animal-cells">
                                        {nickIcons.map((icon) => (
                                            <BaseButton
                                                key={icon.id}
                                                className={cellClass(selectedNickIcon?.id === icon.id, !!icon.active)}
                                                type="button"
                                                onClick={() => setSelectedNickIcon(icon)}
                                            >
                                                {GetNickIconUrl(icon.iconKey) && <img alt={icon.displayName || icon.iconKey} className="octane-inventory-identity-icon" src={GetNickIconUrl(icon.iconKey)} />}
                                            </BaseButton>
                                        ))}
                                    </div>
                                </ClassicScrollAreaView>
                            </div>
                            <div className="octane-inventory-animal-preview">
                                <div className="octane-inventory-animal-name">{selectedNickIcon ? selectedNickIcon.displayName || selectedNickIcon.iconKey : ''}</div>
                                <div className="octane-inventory-animal-image">
                                    {selectedNickIcon && selectedIconUrl && (
                                        <img alt={selectedNickIcon.displayName || selectedNickIcon.iconKey} className="octane-inventory-identity-icon is-large" src={selectedIconUrl} />
                                    )}
                                </div>
                                <div className="octane-inventory-animal-description">
                                    {!selectedNickIcon && activeNickIcon && `${activeLabel}: ${activeNickIcon.displayName || activeNickIcon.iconKey}`}
                                </div>
                                <div className="octane-inventory-animal-actions">
                                    <OctaneButton
                                        className="octane-inventory-animal-place"
                                        disabled={!selectedNickIcon}
                                        onClick={() => (selectedNickIcon.active ? deactivateNickIcon() : activateNickIcon(selectedNickIcon.id))}
                                    >
                                        {selectedNickIcon?.active ? deactivateLabel : activateLabel}
                                    </OctaneButton>
                                </div>
                            </div>
                        </div>
                    ))}
            </div>
        </NativeTextTree>
    );
};
15Sujets
1Dépôts
20Membres
3En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser