Start updating room widgets

This commit is contained in:
Bill 2021-12-04 01:26:46 -05:00
parent d193575966
commit e062b6cf37
5 changed files with 180 additions and 168 deletions

View File

@ -2,6 +2,10 @@ import { ApplyTonerComposer, RoomControllerLevel, RoomEngineObjectEvent, RoomEng
import { FC, useCallback, useEffect, useState } from 'react'; import { FC, useCallback, useEffect, useState } from 'react';
import ReactSlider from 'react-slider'; import ReactSlider from 'react-slider';
import { GetRoomEngine, GetSessionDataManager, LocalizeText, RoomWidgetUpdateBackgroundColorPreviewEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api'; import { GetRoomEngine, GetSessionDataManager, LocalizeText, RoomWidgetUpdateBackgroundColorPreviewEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
import { Button } from '../../../../../common/Button';
import { Column } from '../../../../../common/Column';
import { FormGroup } from '../../../../../common/FormGroup';
import { Text } from '../../../../../common/Text';
import { SendMessageHook } from '../../../../../hooks'; import { SendMessageHook } from '../../../../../hooks';
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../../hooks/events'; import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../../hooks/events';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
@ -86,8 +90,9 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
<NitroCardView> <NitroCardView>
<NitroCardHeaderView headerText={ LocalizeText('widget.backgroundcolor.title') } onCloseClick={ close } /> <NitroCardHeaderView headerText={ LocalizeText('widget.backgroundcolor.title') } onCloseClick={ close } />
<NitroCardContentView> <NitroCardContentView>
<div className="form-group"> <Column overflow="auto">
<label className="fw-bold text-black">{ LocalizeText('widget.backgroundcolor.hue') }</label> <FormGroup column>
<Text fontWeight="bold">{ LocalizeText('widget.backgroundcolor.hue') }</Text>
<ReactSlider <ReactSlider
className={ 'nitro-slider' } className={ 'nitro-slider' }
min={ 0 } min={ 0 }
@ -96,9 +101,9 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
onChange={ event => setHue(event) } onChange={ event => setHue(event) }
thumbClassName={ 'thumb degree' } thumbClassName={ 'thumb degree' }
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } /> renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
</div> </FormGroup>
<div className="form-group"> <FormGroup column>
<label className="fw-bold text-black">{ LocalizeText('widget.backgroundcolor.saturation') }</label> <Text fontWeight="bold">{ LocalizeText('widget.backgroundcolor.saturation') }</Text>
<ReactSlider <ReactSlider
className={ 'nitro-slider' } className={ 'nitro-slider' }
min={ 0 } min={ 0 }
@ -107,9 +112,9 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
onChange={ event => setSaturation(event) } onChange={ event => setSaturation(event) }
thumbClassName={ 'thumb percent' } thumbClassName={ 'thumb percent' }
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } /> renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
</div> </FormGroup>
<div className="form-group mb-2"> <FormGroup column>
<label className="fw-bold text-black">{ LocalizeText('widget.backgroundcolor.lightness') }</label> <Text fontWeight="bold">{ LocalizeText('widget.backgroundcolor.lightness') }</Text>
<ReactSlider <ReactSlider
className={ 'nitro-slider' } className={ 'nitro-slider' }
min={ 0 } min={ 0 }
@ -118,11 +123,16 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
onChange={ event => setLightness(event) } onChange={ event => setLightness(event) }
thumbClassName={ 'thumb percent' } thumbClassName={ 'thumb percent' }
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } /> renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
</div> </FormGroup>
<div className="d-flex form-group justify-content-between align-items-center"> </Column>
<button type="button" className="btn btn-primary" onClick={ event => processAction('toggle') }>{ LocalizeText('widget.backgroundcolor.button.on') }</button> <Column center gap={ 1 }>
<button type="button" className="btn btn-primary" onClick={ event => processAction('apply') }>{ LocalizeText('widget.backgroundcolor.button.apply') }</button> <Button fullWidth variant="primary" size="sm" onClick={ event => processAction('toggle') }>
</div> { LocalizeText('widget.backgroundcolor.button.on') }
</Button>
<Button fullWidth variant="primary" size="sm" onClick={ event => processAction('apply') }>
{ LocalizeText('widget.backgroundcolor.button.apply') }
</Button>
</Column>
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>
); );

View File

@ -3,6 +3,11 @@ import classNames from 'classnames';
import { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import ReactSlider from 'react-slider'; import ReactSlider from 'react-slider';
import { ColorUtils, GetConfiguration, LocalizeText, RoomWidgetDimmerChangeStateMessage, RoomWidgetDimmerPreviewMessage, RoomWidgetDimmerSavePresetMessage, RoomWidgetUpdateDimmerEvent, RoomWidgetUpdateDimmerStateEvent } from '../../../../../api'; import { ColorUtils, GetConfiguration, LocalizeText, RoomWidgetDimmerChangeStateMessage, RoomWidgetDimmerPreviewMessage, RoomWidgetDimmerSavePresetMessage, RoomWidgetUpdateDimmerEvent, RoomWidgetUpdateDimmerStateEvent } from '../../../../../api';
import { Button } from '../../../../../common/Button';
import { Column } from '../../../../../common/Column';
import { Flex } from '../../../../../common/Flex';
import { Grid } from '../../../../../common/Grid';
import { Text } from '../../../../../common/Text';
import { BatchUpdates, CreateEventDispatcherHook } from '../../../../../hooks'; import { BatchUpdates, CreateEventDispatcherHook } from '../../../../../hooks';
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../../layout'; import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../../layout';
import { useRoomContext } from '../../../context/RoomContext'; import { useRoomContext } from '../../../context/RoomContext';
@ -147,45 +152,51 @@ export const FurnitureDimmerView: FC<{}> = props =>
return ( return (
<NitroCardView className="nitro-dimmer"> <NitroCardView className="nitro-dimmer">
<NitroCardHeaderView headerText={ LocalizeText('widget.dimmer.title') } onCloseClick={ close } /> <NitroCardHeaderView headerText={ LocalizeText('widget.dimmer.title') } onCloseClick={ close } />
<NitroCardContentView className="p-0">
{ (dimmerState === 0) &&
<div className="d-flex flex-column gap-2 align-items-center p-2">
<div className="dimmer-banner"></div>
<div className="bg-muted rounded p-1 text-center text-black">{ LocalizeText('widget.dimmer.info.off') }</div>
<button className="btn-success btn w-100" onClick={ toggleState }>{ LocalizeText('widget.dimmer.button.on') }</button>
</div> }
{ (dimmerState === 1) && { (dimmerState === 1) &&
<>
<NitroCardTabsView> <NitroCardTabsView>
{ presets.map(preset => { presets.map(preset =>
{ {
return <NitroCardTabsItemView key={ preset.id } isActive={ (selectedPresetId === preset.id) } onClick={ event => selectPresetId(preset.id) }>{ LocalizeText(`widget.dimmer.tab.${preset.id}`) }</NitroCardTabsItemView> return <NitroCardTabsItemView key={ preset.id } isActive={ (selectedPresetId === preset.id) } onClick={ event => selectPresetId(preset.id) }>{ LocalizeText(`widget.dimmer.tab.${preset.id}`) }</NitroCardTabsItemView>
}) } }) }
</NitroCardTabsView> </NitroCardTabsView> }
<div className="p-2"> <NitroCardContentView>
<div className="form-group mb-2"> { (dimmerState === 0) &&
<label className="fw-bold text-black">{ LocalizeText('widget.backgroundcolor.hue') }</label> <Column alignItems="center">
<div className="dimmer-banner"></div>
<Text center className="bg-muted rounded p-1">{ LocalizeText('widget.dimmer.info.off') }</Text>
<Button fullWidth variant="success" onClick={ toggleState }>{ LocalizeText('widget.dimmer.button.on') }</Button>
</Column> }
{ (dimmerState === 1) &&
<>
<Column gap={ 1 }>
<Text fontWeight="bold">{ LocalizeText('widget.backgroundcolor.hue') }</Text>
{ isFreeColorMode && { isFreeColorMode &&
<input type="color" className="form-control" value={ ColorUtils.makeColorNumberHex(selectedColor) } onChange={ event => setSelectedColor(ColorUtils.convertFromHex(event.target.value)) } /> } <input type="color" className="form-control" value={ ColorUtils.makeColorNumberHex(selectedColor) } onChange={ event => setSelectedColor(ColorUtils.convertFromHex(event.target.value)) } /> }
{ !isFreeColorMode && { !isFreeColorMode &&
<div className="d-flex gap-2"> <Grid columnCount={ 7 }>
{ AVAILABLE_COLORS.map((color, index) => { AVAILABLE_COLORS.map((color, index) =>
{ {
return <div key={ index } className={ 'color-swatch rounded w-100 cursor-pointer' + classNames({ ' active': color === selectedColor }) } onClick={ () => setSelectedColor(color) } style={{ backgroundColor: HTML_COLORS[index] }}></div>; return (
<Column fullWidth pointer key={ index } className={ 'color-swatch rounded' + classNames({ ' active': color === selectedColor }) } onClick={ () => setSelectedColor(color) } style={{ backgroundColor: HTML_COLORS[index] }} />
);
}) } }) }
</div> } </Grid> }
</div> </Column>
<div className="form-group mb-2"> <Column gap={ 1 }>
<label className="fw-bold text-black">{ LocalizeText('widget.backgroundcolor.lightness') }</label> <Text fontWeight="bold">{ LocalizeText('widget.backgroundcolor.lightness') }</Text>
<ReactSlider <ReactSlider
className={ 'nitro-slider' } className="nitro-slider"
min={ MIN_BRIGHTNESS } min={ MIN_BRIGHTNESS }
max={ MAX_BRIGHTNESS } max={ MAX_BRIGHTNESS }
value={ selectedBrightness } value={ selectedBrightness }
onChange={ value => setSelectedBrightness(value) } onChange={ value => setSelectedBrightness(value) }
thumbClassName={ 'thumb percent' } thumbClassName={ 'thumb percent' }
renderThumb={ (props, state) => <div {...props}>{ scaledBrightness(state.valueNow) }</div> } /> renderThumb={ (props, state) => <div {...props}>{ scaledBrightness(state.valueNow) }</div> } />
</div> </Column>
<Flex>
<input className="form-check-input" type="checkbox" checked={ (selectedEffectId === 2) } onChange={ event => setSelectedEffectId(event.target.checked ? 2 : 1) } />
<label className="form-check-label text-black">{ LocalizeText('widget.dimmer.type.checkbox') }</label>
</Flex>
<div className="form-check mb-2"> <div className="form-check mb-2">
<input className="form-check-input" type="checkbox" checked={ (selectedEffectId === 2) } onChange={ event => setSelectedEffectId(event.target.checked ? 2 : 1) } /> <input className="form-check-input" type="checkbox" checked={ (selectedEffectId === 2) } onChange={ event => setSelectedEffectId(event.target.checked ? 2 : 1) } />
<label className="form-check-label text-black">{ LocalizeText('widget.dimmer.type.checkbox') }</label> <label className="form-check-label text-black">{ LocalizeText('widget.dimmer.type.checkbox') }</label>
@ -194,7 +205,6 @@ export const FurnitureDimmerView: FC<{}> = props =>
<button className="btn btn-danger w-100" onClick={ toggleState }>{ LocalizeText('widget.dimmer.button.off') }</button> <button className="btn btn-danger w-100" onClick={ toggleState }>{ LocalizeText('widget.dimmer.button.off') }</button>
<button className="btn btn-success w-100" onClick={ applyChanges }>{ LocalizeText('widget.dimmer.button.apply') }</button> <button className="btn btn-success w-100" onClick={ applyChanges }>{ LocalizeText('widget.dimmer.button.apply') }</button>
</div> </div>
</div>
</> } </> }
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>

View File

@ -1,9 +1,13 @@
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { LocalizeText, RoomWidgetCreditFurniRedeemMessage, RoomWidgetUpdateCreditFurniEvent } from '../../../../../api'; import { LocalizeText, RoomWidgetCreditFurniRedeemMessage, RoomWidgetUpdateCreditFurniEvent } from '../../../../../api';
import { Base } from '../../../../../common/Base';
import { Button } from '../../../../../common/Button';
import { Column } from '../../../../../common/Column';
import { Grid } from '../../../../../common/Grid';
import { Text } from '../../../../../common/Text';
import { BatchUpdates } from '../../../../../hooks'; import { BatchUpdates } from '../../../../../hooks';
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base'; import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutButton, NitroLayoutFlexColumn, NitroLayoutGrid, NitroLayoutGridColumn } from '../../../../../layout'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
import { NitroLayoutBase } from '../../../../../layout/base';
import { useRoomContext } from '../../../context/RoomContext'; import { useRoomContext } from '../../../context/RoomContext';
export const FurnitureExchangeCreditView: FC<{}> = props => export const FurnitureExchangeCreditView: FC<{}> = props =>
@ -42,24 +46,20 @@ export const FurnitureExchangeCreditView: FC<{}> = props =>
<NitroCardView className="nitro-widget-exchange-credit" simple={ true }> <NitroCardView className="nitro-widget-exchange-credit" simple={ true }>
<NitroCardHeaderView headerText={ LocalizeText('catalog.redeem.dialog.title') } onCloseClick={ close } /> <NitroCardHeaderView headerText={ LocalizeText('catalog.redeem.dialog.title') } onCloseClick={ close } />
<NitroCardContentView> <NitroCardContentView>
<NitroLayoutGrid> <Grid>
<NitroLayoutGridColumn className="justify-content-center align-items-center" overflow="hidden" size={ 4 }> <Column center overflow="hidden" size={ 4 }>
<NitroLayoutBase className="exchange-image" /> <Base className="exchange-image" />
</NitroLayoutGridColumn> </Column>
<NitroLayoutGridColumn className="justify-content-between" overflow="hidden" size={ 8 }> <Column justifyContent="between" overflow="hidden" size={ 8 }>
<NitroLayoutFlexColumn gap={ 1 } overflow="auto"> <Column gap={ 1 } overflow="auto">
<NitroLayoutBase className="text-black fw-bold"> <Text fontWeight="bold">{ LocalizeText('creditfurni.description', [ 'credits' ], [ value.toString() ]) }</Text>
{ LocalizeText('creditfurni.description', [ 'credits' ], [ value.toString() ]) } <Text>{ LocalizeText('creditfurni.prompt') }</Text>
</NitroLayoutBase> </Column>
<NitroLayoutBase className="text-black"> <Button variant="success" onClick={ redeem }>
{ LocalizeText('creditfurni.prompt') }
</NitroLayoutBase>
</NitroLayoutFlexColumn>
<NitroLayoutButton variant="success" onClick={ redeem }>
{ LocalizeText('catalog.redeem.dialog.button.exchange') } { LocalizeText('catalog.redeem.dialog.button.exchange') }
</NitroLayoutButton> </Button>
</NitroLayoutGridColumn> </Column>
</NitroLayoutGrid> </Grid>
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>
); );

View File

@ -1,10 +1,14 @@
import { AvatarFigurePartType, FurnitureMannequinSaveLookComposer, FurnitureMannequinSaveNameComposer, FurnitureMultiStateComposer, HabboClubLevelEnum, IAvatarFigureContainer, RoomControllerLevel } from '@nitrots/nitro-renderer'; import { AvatarFigurePartType, FurnitureMannequinSaveLookComposer, FurnitureMannequinSaveNameComposer, FurnitureMultiStateComposer, HabboClubLevelEnum, IAvatarFigureContainer, RoomControllerLevel } from '@nitrots/nitro-renderer';
import { FC, KeyboardEvent, useCallback, useEffect, useState } from 'react'; import { FC, KeyboardEvent, useCallback, useEffect, useState } from 'react';
import { GetAvatarRenderManager, GetSessionDataManager, LocalizeText, RoomWidgetUpdateMannequinEvent } from '../../../../../api'; import { GetAvatarRenderManager, GetSessionDataManager, LocalizeText, RoomWidgetUpdateMannequinEvent } from '../../../../../api';
import { Button } from '../../../../../common/Button';
import { Column } from '../../../../../common/Column';
import { Flex } from '../../../../../common/Flex';
import { Grid } from '../../../../../common/Grid';
import { Text } from '../../../../../common/Text';
import { BatchUpdates, SendMessageHook } from '../../../../../hooks'; import { BatchUpdates, SendMessageHook } from '../../../../../hooks';
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base'; import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutButton, NitroLayoutFlex, NitroLayoutFlexColumn, NitroLayoutGrid, NitroLayoutGridColumn } from '../../../../../layout'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
import { NitroLayoutBase } from '../../../../../layout/base';
import { useRoomContext } from '../../../context/RoomContext'; import { useRoomContext } from '../../../context/RoomContext';
import { FurnitureMannequinPreviewView } from './views/preview/FurnitureMannequinPreviewView'; import { FurnitureMannequinPreviewView } from './views/preview/FurnitureMannequinPreviewView';
@ -169,68 +173,52 @@ export const FurnitureMannequinView: FC<{}> = props =>
<NitroCardView className="nitro-mannequin" simple={ true }> <NitroCardView className="nitro-mannequin" simple={ true }>
<NitroCardHeaderView headerText={ LocalizeText('mannequin.widget.title') } onCloseClick={ event => setMode(MODE_NONE) } /> <NitroCardHeaderView headerText={ LocalizeText('mannequin.widget.title') } onCloseClick={ event => setMode(MODE_NONE) } />
<NitroCardContentView> <NitroCardContentView>
<NitroLayoutGrid> <Grid>
<NitroLayoutGridColumn className="justify-content-center align-items-center" overflow="hidden" size={ 4 }> <Column center size={ 4 } overflow="hidden">
<FurnitureMannequinPreviewView figure={ renderedFigure } clubLevel={ renderedClubLevel } /> <FurnitureMannequinPreviewView figure={ renderedFigure } clubLevel={ renderedClubLevel } />
</NitroLayoutGridColumn> </Column>
<NitroLayoutGridColumn className="justify-content-between" overflow="hidden" size={ 8 }> <Column size={ 8 } justifyContent="between" overflow="hidden">
{ (mode === MODE_CONTROLLER) && { (mode === MODE_CONTROLLER) &&
<> <>
<NitroLayoutFlexColumn gap={ 1 } overflow="auto">
<input type="text" className="form-control" value={ name } onChange={ event => setName(event.target.value) } onKeyDown={ event => handleKeyDown(event) } /> <input type="text" className="form-control" value={ name } onChange={ event => setName(event.target.value) } onKeyDown={ event => handleKeyDown(event) } />
</NitroLayoutFlexColumn> <Column gap={ 1 } overflow="auto">
<NitroLayoutFlexColumn gap={ 1 }> <Button variant="success" onClick={ event => setMode(MODE_UPDATE) }>
<NitroLayoutButton variant="success" onClick={ event => setMode(MODE_UPDATE) }>
{ LocalizeText('mannequin.widget.style') } { LocalizeText('mannequin.widget.style') }
</NitroLayoutButton> </Button>
<NitroLayoutButton variant="success" onClick={ event => processAction(ACTION_WEAR) }> <Button variant="success" onClick={ event => processAction(ACTION_WEAR) }>
{ LocalizeText('mannequin.widget.wear') } { LocalizeText('mannequin.widget.wear') }
</NitroLayoutButton> </Button>
</NitroLayoutFlexColumn> </Column>
</> } </> }
{ (mode === MODE_UPDATE) && { (mode === MODE_UPDATE) &&
<> <>
<NitroLayoutFlexColumn gap={ 1 } overflow="auto"> <Column gap={ 1 } overflow="auto">
<NitroLayoutBase className="text-black fw-bold"> <Text fontWeight="bold">{ name }</Text>
{ name } <Text>{ LocalizeText('mannequin.widget.savetext') }</Text>
</NitroLayoutBase> </Column>
<NitroLayoutBase className="text-black"> <Flex alignItems="center" justifyContent="between">
{ LocalizeText('mannequin.widget.savetext') } <Text underline pointer onClick={ event => setMode(MODE_CONTROLLER) }>
</NitroLayoutBase>
</NitroLayoutFlexColumn>
<NitroLayoutFlex className="justify-content-between align-items-center">
<NitroLayoutBase className="text-black text-decoration-underline cursor-pointer" onClick={ event => setMode(MODE_CONTROLLER) }>
{ LocalizeText('mannequin.widget.back') } { LocalizeText('mannequin.widget.back') }
</NitroLayoutBase> </Text>
<NitroLayoutButton variant="success" onClick={ event => processAction(ACTION_SAVE) }> <Button variant="success" onClick={ event => processAction(ACTION_SAVE) }>
{ LocalizeText('mannequin.widget.save') } { LocalizeText('mannequin.widget.save') }
</NitroLayoutButton> </Button>
</NitroLayoutFlex> </Flex>
</> } </> }
{ (mode === MODE_PEER) && { (mode === MODE_PEER) &&
<> <>
<NitroLayoutFlexColumn gap={ 1 } overflow="auto"> <Column gap={ 1 } overflow="auto">
<NitroLayoutBase className="text-black fw-bold"> <Text fontWeight="bold">{ name }</Text>
{ name } <Text>{ LocalizeText('mannequin.widget.weartext') }</Text>
</NitroLayoutBase> </Column>
<NitroLayoutBase className="text-black"> <Button variant="success" onClick={ event => processAction(ACTION_WEAR) }>
{ LocalizeText('mannequin.widget.weartext') }
</NitroLayoutBase>
</NitroLayoutFlexColumn>
<NitroLayoutButton variant="success" onClick={ event => processAction(ACTION_WEAR) }>
{ LocalizeText('mannequin.widget.wear') } { LocalizeText('mannequin.widget.wear') }
</NitroLayoutButton> </Button>
</> } </> }
{ (mode === MODE_NO_CLUB) && { (mode === MODE_NO_CLUB) && <Text>{ LocalizeText('mannequin.widget.clubnotification') }</Text> }
<NitroLayoutBase className="text-black"> { (mode === MODE_WRONG_GENDER) && <Text>{ LocalizeText('mannequin.widget.wronggender') }</Text> }
{ LocalizeText('mannequin.widget.clubnotification') } </Column>
</NitroLayoutBase> } </Grid>
{ (mode === MODE_WRONG_GENDER) &&
<NitroLayoutBase className="text-black">
{ LocalizeText('mannequin.widget.wronggender') }
</NitroLayoutBase> }
</NitroLayoutGridColumn>
</NitroLayoutGrid>
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>
); );

View File

@ -1,10 +1,13 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, RoomSessionUserBadgesEvent, UserRelationshipsComposer } from '@nitrots/nitro-renderer'; import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, RoomSessionUserBadgesEvent, UserRelationshipsComposer } from '@nitrots/nitro-renderer';
import classNames from 'classnames'; import classNames from 'classnames';
import { FC, FocusEvent, KeyboardEvent, useCallback, useEffect, useState } from 'react'; import { FC, FocusEvent, KeyboardEvent, useCallback, useEffect, useState } from 'react';
import { GetGroupInformation, LocalizeText, RoomWidgetChangeMottoMessage, RoomWidgetUpdateInfostandUserEvent } from '../../../../../../api'; import { GetGroupInformation, LocalizeText, RoomWidgetChangeMottoMessage, RoomWidgetUpdateInfostandUserEvent } from '../../../../../../api';
import { Base } from '../../../../../../common/Base';
import { Flex } from '../../../../../../common/Flex';
import { CreateMessageHook, SendMessageHook } from '../../../../../../hooks'; import { CreateMessageHook, SendMessageHook } from '../../../../../../hooks';
import { CreateEventDispatcherHook } from '../../../../../../hooks/events'; import { CreateEventDispatcherHook } from '../../../../../../hooks/events';
import { NitroLayoutFlex, UserProfileIconView } from '../../../../../../layout'; import { UserProfileIconView } from '../../../../../../layout';
import { AvatarImageView } from '../../../../../shared/avatar-image/AvatarImageView'; import { AvatarImageView } from '../../../../../shared/avatar-image/AvatarImageView';
import { BadgeImageView } from '../../../../../shared/badge-image/BadgeImageView'; import { BadgeImageView } from '../../../../../shared/badge-image/BadgeImageView';
import { RelationshipsContainerView } from '../../../../../user-profile/views/relationships-container/RelationshipsContainerView'; import { RelationshipsContainerView } from '../../../../../user-profile/views/relationships-container/RelationshipsContainerView';
@ -82,60 +85,61 @@ export const InfoStandWidgetUserView: FC<InfoStandWidgetUserViewProps> = props =
if(!userData) return null; if(!userData) return null;
return ( return (
<div className="d-flex flex-column nitro-card nitro-infostand rounded"> <Flex column className="nitro-card nitro-infostand rounded">
<div className="container-fluid content-area overflow-visible"> <div className="container-fluid content-area overflow-visible">
<div className="d-flex justify-content-between align-items-center"> <Flex center>
<NitroLayoutFlex className="align-items-center"> <Flex alignItems="center">
<UserProfileIconView userId={ userData.webID } /> <UserProfileIconView userId={ userData.webID } />
<span className="small text-wrap">{ userData.name }</span> <span className="small text-wrap">{ userData.name }</span>
</NitroLayoutFlex> </Flex>
<i className="fas fa-times cursor-pointer" onClick={ close }></i> <FontAwesomeIcon icon="times" className="cursor-pointer" onClick={ close } />
</div> </Flex>
<hr className="m-0 my-1" /> <hr className="m-0 my-1" />
<div className="d-flex"> <Flex>
<div className="body-image w-100"> <div className="body-image w-100">
<AvatarImageView figure={ userData.figure } direction={ 4 } /> <AvatarImageView figure={ userData.figure } direction={ 4 } />
</div> </div>
<div> <div>
<div className="d-flex justify-content-between"> <Flex justifyContent="between">
<div className="badge-image"> <div className="badge-image">
{ badges[0] && <BadgeImageView badgeCode={ badges[0] } showInfo={ true } /> } { badges[0] && <BadgeImageView badgeCode={ badges[0] } showInfo={ true } /> }
</div> </div>
<div className={ 'badge-image' + classNames({ ' cursor-pointer': userData.groupId > 0 }) } onClick={ () => GetGroupInformation(userData.groupId) }> <div className={ 'badge-image' + classNames({ ' cursor-pointer': userData.groupId > 0 }) } onClick={ () => GetGroupInformation(userData.groupId) }>
{ userData.groupId > 0 && <BadgeImageView badgeCode={ userData.groupBadgeId } isGroup={ true } showInfo={ true } customTitle={ userData.groupName } /> } { userData.groupId > 0 && <BadgeImageView badgeCode={ userData.groupBadgeId } isGroup={ true } showInfo={ true } customTitle={ userData.groupName } /> }
</div> </div>
</div> </Flex>
<div className="d-flex justify-content-between"> <Flex justifyContent="between">
<div className="badge-image"> <div className="badge-image">
{ badges[1] && <BadgeImageView badgeCode={ badges[1] } showInfo={ true } /> } { badges[1] && <BadgeImageView badgeCode={ badges[1] } showInfo={ true } /> }
</div> </div>
<div className="badge-image"> <div className="badge-image">
{ badges[2] && <BadgeImageView badgeCode={ badges[2] } showInfo={ true } /> } { badges[2] && <BadgeImageView badgeCode={ badges[2] } showInfo={ true } /> }
</div> </div>
</div> </Flex>
<div className="d-flex justify-content-between"> <Flex justifyContent="between">
<div className="badge-image"> <div className="badge-image">
{ badges[3] && <BadgeImageView badgeCode={ badges[3] } showInfo={ true } /> } { badges[3] && <BadgeImageView badgeCode={ badges[3] } showInfo={ true } /> }
</div> </div>
<div className="badge-image"> <div className="badge-image">
{ badges[4] && <BadgeImageView badgeCode={ badges[4] } showInfo={ true } /> } { badges[4] && <BadgeImageView badgeCode={ badges[4] } showInfo={ true } /> }
</div> </div>
</Flex>
</div> </div>
</div> </Flex>
</div>
<hr className="m-0 my-1" /> <hr className="m-0 my-1" />
<div className="bg-light-dark rounded py-1 px-2 small"> <div className="bg-light-dark rounded py-1 px-2 small">
{ userData.type !== RoomWidgetUpdateInfostandUserEvent.OWN_USER && <div className="motto-content w-100 text-wrap text-break">{ motto }</div> } { (userData.type !== RoomWidgetUpdateInfostandUserEvent.OWN_USER) &&
<div className="motto-content w-100 text-wrap text-break">{ motto }</div> }
{ userData.type === RoomWidgetUpdateInfostandUserEvent.OWN_USER && { userData.type === RoomWidgetUpdateInfostandUserEvent.OWN_USER &&
<div className="d-flex justify-content-between align-items-center"> <Flex justifyContent="between" alignItems="center">
<i className="small fas fa-pencil-alt me-2"></i> <FontAwesomeIcon icon="pencil-alt" className="small me-2" />
<div className="h-100 w-100"> <Base fit>
{ !isEditingMotto && { !isEditingMotto &&
<div className="motto-content cursor-pointer w-100 text-wrap text-break" onClick={ event => setIsEditingMotto(true) }>{ motto }</div> } <div className="motto-content cursor-pointer w-100 text-wrap text-break" onClick={ event => setIsEditingMotto(true) }>{ motto }</div> }
{ isEditingMotto && { isEditingMotto &&
<input type="text" className="motto-input" maxLength={ 38 } value={ motto } onChange={ event => setMotto(event.target.value) } onBlur={ onMottoBlur } onKeyDown={ onMottoKeyDown } autoFocus={ true } /> } <input type="text" className="motto-input" maxLength={ 38 } value={ motto } onChange={ event => setMotto(event.target.value) } onBlur={ onMottoBlur } onKeyDown={ onMottoKeyDown } autoFocus={ true } /> }
</div> </Base>
</div> } </Flex> }
</div> </div>
<hr className="m-0 my-1" /> <hr className="m-0 my-1" />
<div className="small text-wrap"> <div className="small text-wrap">
@ -151,5 +155,5 @@ export const InfoStandWidgetUserView: FC<InfoStandWidgetUserViewProps> = props =
} }
<RelationshipsContainerView relationships={userRelationships} simple={true}/> <RelationshipsContainerView relationships={userRelationships} simple={true}/>
</div> </div>
</div>); </Flex>);
} }