5180 fichiers 38.5 Mo 0 téléchargements 275 vues mis à jour il y a 6 heures ui
nitro-v36-with-renderer-v36 / src / components / groups / views / GroupInformationNativeView.tsx
GroupInformationNativeView.tsx 10.6 Ko Télécharger le fichier
import { CreateLinkEvent, GetSessionDataManager, GroupDeleteComposer, GroupInformationParser } from '@octane/renderer';
import { FC, useLayoutEffect, useRef } from 'react';
import {
    CatalogPageName,
    GetGroupManager,
    GetGroupMembers,
    GroupMembershipType,
    GroupType,
    LocalizeText,
    SendMessageComposer,
    TryJoinGroup,
    TryVisitRoom
} from '../../../api';
import decorateIcon from '../../../assets/images/groups/native/group_decorate_icon.png';
import adminIcon from '../../../assets/images/groups/native/group_icon_big_admin.png';
import memberIcon from '../../../assets/images/groups/native/group_icon_big_member.png';
import ownerIcon from '../../../assets/images/groups/native/group_icon_big_owner.png';
import typeIconRegular from '../../../assets/images/groups/native/grouptype_icon_5.png';
import typeIconExclusive from '../../../assets/images/groups/native/grouptype_icon_1.png';
import typeIconPrivate from '../../../assets/images/groups/native/grouptype_icon_2.png';
import { LayoutBadgeImageView } from '../../../common';
import { useGroupLeave, useNotification } from '../../../hooks';
import { flatText, GroupBox, GroupButton, GroupText } from './GroupNativeLayout';
import { Hint } from '../../../common/Tooltip';

const TYPE_ICONS: string[] = [typeIconRegular, typeIconExclusive, typeIconPrivate];
const TYPE_HELP: string[] = ['regular', 'exclusive', 'private'];

// groups_info_window: group_cont is the style 0 border at (10,10) below the 33px frame margin, 343x214; every rectangle below is its layout rectangle.
const BASE_X = 10;
const BASE_Y = 43;

interface GroupInformationNativeViewProps {
    groupInformation: GroupInformationParser;
}

/** groups_info_window: the official 363x268 group information window. */
export const GroupInformationNativeView: FC<GroupInformationNativeViewProps> = (props) => {
    const { groupInformation = null } = props;
    const { showConfirm = null } = useNotification();
    const shownGroupId = groupInformation?.id ?? 0;
    const shownGroupIdRef = useRef<number>(shownGroupId);
    const leaveGroup = useGroupLeave(shownGroupId);

    // Read by the delete confirmation; refreshed before it can run.
    useLayoutEffect(() => {
        shownGroupIdRef.current = shownGroupId;
    });

    if (!groupInformation) return null;

    const isRealOwner = groupInformation.isOwner;
    const isMember = groupInformation.membershipType === GroupMembershipType.MEMBER;
    const isPending = groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING;
    const isNotMember = groupInformation.membershipType === GroupMembershipType.NOT_MEMBER;
    const nameX = BASE_X + 125 + (groupInformation.canMembersDecorate ? 15 : 0);

    // Below the Members line the owner's Manage and Delete links follow, one line lower while a Pending line is shown.
    const hasPendingLine = groupInformation.pendingRequestsCount > 0 && (groupInformation.isOwner || groupInformation.isAdmin);
    const leftLinksY = hasPendingLine ? 137 : 121;
    // GroupDetailsCtrl: delete_guild_region shows for the owner, or for staff with security level 5.
    const canDelete = groupInformation.isOwner || GetSessionDataManager().hasSecurity(5);

    const deleteGroup = () => {
        let isSent = false;

        showConfirm(
            LocalizeText('group.deleteconfirm.desc'),
            () => {
                // One deletion per confirmation, and only while that group is the one shown.
                if (isSent || groupInformation.id !== shownGroupIdRef.current) return;

                isSent = true;
                SendMessageComposer(new GroupDeleteComposer(groupInformation.id));
            },
            null,
            null,
            null,
            LocalizeText('group.deleteconfirm.title')
        );
    };

    const handleAction = (action: string) => {
        switch (action) {
            case 'members':
                GetGroupMembers(groupInformation.id, 0);
                break;
            case 'members_pending':
                GetGroupMembers(groupInformation.id, 2);
                break;
            case 'manage':
                GetGroupManager(groupInformation.id);
                break;
            case 'homeroom':
                TryVisitRoom(groupInformation.roomId);
                break;
            case 'furniture':
                CreateLinkEvent('catalog/open/' + CatalogPageName.GUILD_CUSTOM_FURNI);
                break;
            case 'popular_groups':
                CreateLinkEvent('navigator/search/groups');
                break;
            case 'forum':
                CreateLinkEvent('groupforum/' + groupInformation.id);
                break;
        }
    };

    return (
        <>
            <GroupBox height={214} kind="cc" width={343} x={BASE_X} y={BASE_Y} />
            <div className="octane-group-info__badge" style={{ left: BASE_X + 11, top: BASE_Y + 14 }}>
                <LayoutBadgeImageView badgeCode={groupInformation.badge} isGroup={true} scale={2} />
            </div>
            <Hint content={LocalizeText(`group.edit.settings.type.${TYPE_HELP[groupInformation.type]}.help`)}><img alt={LocalizeText(`group.edit.settings.type.${TYPE_HELP[groupInformation.type]}.help`)} className="octane-group-info__icon" draggable={false} src={TYPE_ICONS[groupInformation.type]} style={{ left: BASE_X + 107, top: BASE_Y + 10 }} /></Hint>
            {groupInformation.canMembersDecorate && (
                <Hint content={LocalizeText('group.memberscandecorate')}><img alt={LocalizeText('group.memberscandecorate')} className="octane-group-info__icon" draggable={false} src={decorateIcon} style={{ left: BASE_X + 125, top: BASE_Y + 10 }} /></Hint>
            )}
            <GroupText background={0xcccccc} height={17} overrides={flatText(12, { bold: true })} text={groupInformation.title} width={206} x={nameX} y={BASE_Y + 9} />
            <GroupText
                background={0xcccccc}
                text={LocalizeText('group.created', ['date', 'owner'], [groupInformation.createdAt, groupInformation.ownerName])}
                textStyle="u_small"
                x={BASE_X + 103}
                y={BASE_Y + 27}
            />
            <GroupText background={0xcccccc} height={55} overrides={flatText(12)} text={groupInformation.description} width={215} wrap x={BASE_X + 103} y={BASE_Y + 42} />
            <GroupText
                align="center"
                background={0xcccccc}
                className="is-link"
                overrides={flatText(12, { bold: true, underline: true })}
                text={LocalizeText('group.membercount', ['totalMembers'], [groupInformation.membersCount.toString()])}
                width={97}
                x={BASE_X + 4}
                y={BASE_Y + 103}
                onClick={() => handleAction('members')}
            />
            {hasPendingLine && (
                <GroupText
                    align="center"
                    background={0xcccccc}
                    className="is-link"
                    overrides={{ underline: true }}
                    text={LocalizeText('group.pendingmembercount', ['amount'], [groupInformation.pendingRequestsCount.toString()])}
                    textStyle="u_bold"
                    width={97}
                    x={BASE_X + 4}
                    y={BASE_Y + 121}
                    onClick={() => handleAction('members_pending')}
                />
            )}
            <GroupText background={0xcccccc} className="is-link" overrides={flatText(12, { underline: true })} text={LocalizeText('group.linktobase')} x={BASE_X + 103} y={BASE_Y + 103} onClick={() => handleAction('homeroom')} />
            <GroupText background={0xcccccc} className="is-link" overrides={flatText(12, { underline: true })} text={LocalizeText('group.buyfurni')} x={BASE_X + 103} y={BASE_Y + 121} onClick={() => handleAction('furniture')} />
            <GroupText background={0xcccccc} className="is-link" overrides={flatText(12, { underline: true })} text={LocalizeText('group.showgroups')} x={BASE_X + 103} y={BASE_Y + 139} onClick={() => handleAction('popular_groups')} />
            {groupInformation.hasForum && (
                <GroupText background={0xcccccc} className="is-link" overrides={flatText(12, { underline: true })} text={LocalizeText('group.showforum')} x={BASE_X + 103} y={BASE_Y + 157} onClick={() => handleAction('forum')} />
            )}
            {groupInformation.isOwner && (
                <GroupText align="center" background={0xcccccc} className="is-link" overrides={flatText(12, { underline: true })} text={LocalizeText('group.manage')} width={97} x={BASE_X - 1} y={BASE_Y + leftLinksY} onClick={() => handleAction('manage')} />
            )}
            {canDelete && (
                <GroupText align="center" background={0xcccccc} className="is-link" overrides={flatText(12, { underline: true })} text={LocalizeText('group.delete')} width={97} x={BASE_X - 1} y={BASE_Y + leftLinksY + (groupInformation.isOwner ? 16 : 0)} onClick={deleteGroup} />
            )}
            {isMember && !isRealOwner && (
                <>
                    <img
                        alt=""
                        className="octane-group-info__icon"
                        draggable={false}
                        src={groupInformation.isAdmin ? adminIcon : memberIcon}
                        style={{ left: BASE_X + 40, top: BASE_Y + 183 }}
                        title={LocalizeText(groupInformation.isAdmin ? 'group.youareadmin' : 'group.youaremember')}
                    />
                    <GroupButton height={29} label={LocalizeText('group.leave')} width={160} x={BASE_X + 99} y={BASE_Y + 179} onClick={leaveGroup} />
                </>
            )}
            {isRealOwner && (
                <Hint content={LocalizeText('group.youareowner')}><img alt={LocalizeText('group.youareowner')} className="octane-group-info__icon" draggable={false} src={ownerIcon} style={{ left: BASE_X + 40, top: BASE_Y + 183 }} /></Hint>
            )}
            {isNotMember && groupInformation.type === GroupType.REGULAR && (
                <GroupButton height={29} label={LocalizeText('group.join')} width={160} x={BASE_X + 99} y={BASE_Y + 179} onClick={() => TryJoinGroup(groupInformation.id)} />
            )}
            {isNotMember && groupInformation.type === GroupType.EXCLUSIVE && (
                <GroupButton height={29} label={LocalizeText('group.requestmembership')} width={260} x={BASE_X + 49} y={BASE_Y + 179} onClick={() => TryJoinGroup(groupInformation.id)} />
            )}
            {isPending && (
                <GroupText align="center" background={0xcccccc} overrides={flatText(13, { bold: true })} text={LocalizeText('group.membershippending')} width={175} x={BASE_X + 84} y={BASE_Y + 184} />
            )}
        </>
    );
};
15Sujets
1Dépôts
20Membres
2En 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