mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-22 22:30:52 +01:00
Merge branch 'fix-monsterplant-info-like-habbo' into '@fix/fixes'
Fix monsterplant info like habbo (Issue #72 - Look in !73) (read desc) See merge request nitro/nitro-react!76
This commit is contained in:
commit
d658907b45
9
src/api/utils/ConvertSeconds.ts
Normal file
9
src/api/utils/ConvertSeconds.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export const ConvertSeconds = (seconds: number) =>
|
||||
{
|
||||
let numDays = Math.floor(seconds / 86400);
|
||||
let numHours = Math.floor((seconds % 86400) / 3600);
|
||||
let numMinutes = Math.floor(((seconds % 86400) % 3600) / 60);
|
||||
let numSeconds = ((seconds % 86400) % 3600) % 60;
|
||||
|
||||
return numDays.toString().padStart(2, '0') + ':' + numHours.toString().padStart(2, '0') + ':' + numMinutes.toString().padStart(2, '0') + ':' + numSeconds.toString().padStart(2, '0');
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
export * from './CloneObject';
|
||||
export * from './ColorUtils';
|
||||
export * from './ConvertSeconds';
|
||||
export * from './LocalizeBadgeDescription';
|
||||
export * from './LocalizeBageName';
|
||||
export * from './LocalizeFormattedNumber';
|
||||
|
BIN
src/assets/images/infostand/countown-timer.png
Normal file
BIN
src/assets/images/infostand/countown-timer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 219 B |
@ -301,6 +301,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
.nitro-counter-time {
|
||||
width: 36px;
|
||||
height: 28px;
|
||||
background: url("../assets/images/infostand/countown-timer.png");
|
||||
|
||||
div {
|
||||
line-height: 28px;
|
||||
text-align: center;
|
||||
color: $white;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
position: relative;
|
||||
width: 90px;
|
||||
|
65
src/common/layout/LayoutCounterTimeView.tsx
Normal file
65
src/common/layout/LayoutCounterTimeView.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
import { FC, useMemo } from 'react';
|
||||
import { Base, BaseProps, Column, Flex, Text } from '..';
|
||||
import { LocalizeText } from '../../api';
|
||||
|
||||
interface LayoutCounterTimeViewProps extends BaseProps<HTMLDivElement>
|
||||
{
|
||||
day: string;
|
||||
hour: string;
|
||||
minutes: string;
|
||||
seconds: string;
|
||||
}
|
||||
|
||||
export const LayoutCounterTimeView: FC<LayoutCounterTimeViewProps> = props =>
|
||||
{
|
||||
const { day = '00', hour = '00', minutes = '00', seconds = '00', classNames = [], children = null, ...rest } = props;
|
||||
|
||||
const getClassNames = useMemo(() =>
|
||||
{
|
||||
const newClassNames: string[] = [ 'nitro-counter-time' ];
|
||||
|
||||
if(classNames.length) newClassNames.push(...classNames);
|
||||
|
||||
return newClassNames;
|
||||
}, [ classNames ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Column gap={ 1 }>
|
||||
<Flex gap={ 1 }>
|
||||
<Column>
|
||||
<Base classNames={ getClassNames } { ...rest }>
|
||||
<div>{ day != '00' ? day : hour }</div>
|
||||
{ children }
|
||||
</Base>
|
||||
<Text variant="white" small truncate center={ true }>{ day != '00' ? LocalizeText('countdown_clock_unit_days') : LocalizeText('countdown_clock_unit_hours') }</Text>
|
||||
</Column>
|
||||
<Column>
|
||||
<Base style={ { marginTop: '3px' } }>
|
||||
:
|
||||
</Base>
|
||||
</Column>
|
||||
<Column>
|
||||
<Base classNames={ getClassNames } { ...rest }>
|
||||
<div>{ minutes }</div>
|
||||
{ children }
|
||||
</Base>
|
||||
<Text variant="white" small truncate center={ true }>{ LocalizeText('countdown_clock_unit_minutes') }</Text>
|
||||
</Column>
|
||||
<Column>
|
||||
<Base style={ { marginTop: '3px' } }>
|
||||
:
|
||||
</Base>
|
||||
</Column>
|
||||
<Column>
|
||||
<Base classNames={ getClassNames } { ...rest }>
|
||||
<div>{ seconds }</div>
|
||||
{ children }
|
||||
</Base>
|
||||
<Text variant="white" small truncate center={ true }>{ LocalizeText('countdown_clock_unit_seconds') }</Text>
|
||||
</Column>
|
||||
</Flex>
|
||||
</Column>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
export * from './LayoutAvatarImageView';
|
||||
export * from './LayoutBackgroundImage';
|
||||
export * from './LayoutBadgeImageView';
|
||||
export * from './LayoutCounterTimeView';
|
||||
export * from './LayoutCurrencyIcon';
|
||||
export * from './LayoutFurniIconImageView';
|
||||
export * from './LayoutFurniImageView';
|
||||
|
@ -70,6 +70,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.body-image-plant {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
max-width: 68px;
|
||||
height: 85px;
|
||||
max-height: 90px;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
|
||||
.badge-image {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { PetRespectComposer, PetType } from '@nitrots/nitro-renderer';
|
||||
import { FC } from 'react';
|
||||
import { AvatarInfoPet, CreateLinkEvent, GetConfiguration, LocalizeText, SendMessageComposer } from '../../../../../api';
|
||||
import { Base, Button, Column, Flex, LayoutPetImageView, Text, UserProfileIconView } from '../../../../../common';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { AvatarInfoPet, CreateLinkEvent, GetConfiguration, LocalizeText, SendMessageComposer, ConvertSeconds } from '../../../../../api';
|
||||
import { Base, Button, Column, Flex, LayoutPetImageView, LayoutRarityLevelView, Text, UserProfileIconView, LayoutCounterTimeView } from '../../../../../common';
|
||||
import { useRoom, useSessionInfo } from '../../../../../hooks';
|
||||
|
||||
interface InfoStandWidgetPetViewProps
|
||||
@ -14,9 +14,30 @@ interface InfoStandWidgetPetViewProps
|
||||
export const InfoStandWidgetPetView: FC<InfoStandWidgetPetViewProps> = props =>
|
||||
{
|
||||
const { avatarInfo = null, onClose = null } = props;
|
||||
const [ remainingGrowTime, setRemainingGrowTime ] = useState(0);
|
||||
const [ remainingTimeToLive, setRemainingTimeToLive ] = useState(0);
|
||||
const { roomSession = null } = useRoom();
|
||||
const { petRespectRemaining = 0, respectPet = null } = useSessionInfo();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setRemainingGrowTime(avatarInfo.remainingGrowTime);
|
||||
setRemainingTimeToLive(avatarInfo.remainingTimeToLive);
|
||||
}, [ avatarInfo ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if((avatarInfo.petType !== PetType.MONSTERPLANT) || avatarInfo.dead) return;
|
||||
|
||||
const interval = setInterval(() =>
|
||||
{
|
||||
setRemainingGrowTime(prevValue => (prevValue - 1));
|
||||
setRemainingTimeToLive(prevValue => (prevValue - 1));
|
||||
}, 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [ avatarInfo ]);
|
||||
|
||||
if(!avatarInfo) return null;
|
||||
|
||||
const processButtonAction = (action: string) =>
|
||||
@ -64,51 +85,95 @@ export const InfoStandWidgetPetView: FC<InfoStandWidgetPetViewProps> = props =>
|
||||
<Text variant="white" small wrap>{ LocalizeText(`pet.breed.${ avatarInfo.petType }.${ avatarInfo.petBreed }`) }</Text>
|
||||
<hr className="m-0" />
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
<Flex gap={ 1 }>
|
||||
<Column fullWidth overflow="hidden" className="body-image pet p-1">
|
||||
<LayoutPetImageView figure={ avatarInfo.petFigure } posture={ avatarInfo.posture } direction={ 4 } />
|
||||
{ (avatarInfo.petType === PetType.MONSTERPLANT) &&
|
||||
<>
|
||||
<Column gap={ 1 }>
|
||||
<Flex gap={ 1 }>
|
||||
<Column fullWidth overflow="hidden" className="body-image-plant pet p-1">
|
||||
<LayoutPetImageView figure={ avatarInfo.petFigure } posture={ avatarInfo.posture } direction={ 4 } />
|
||||
</Column>
|
||||
{ !avatarInfo.dead &&
|
||||
<Column grow gap={ 1 }>
|
||||
<Text variant="white" center small wrap>{ LocalizeText('pet.level', [ 'level', 'maxlevel' ], [ avatarInfo.level.toString(), avatarInfo.maximumLevel.toString() ]) }</Text>
|
||||
</Column> }
|
||||
</Flex>
|
||||
<hr className="m-0" />
|
||||
</Column>
|
||||
<Column grow gap={ 1 }>
|
||||
<Text variant="white" center small wrap>{ LocalizeText('pet.level', [ 'level', 'maxlevel' ], [ avatarInfo.level.toString(), avatarInfo.maximumLevel.toString() ]) }</Text>
|
||||
<Column gap={ 1 }>
|
||||
<Column alignItems="center" gap={ 1 }>
|
||||
<Text variant="white" small truncate>{ LocalizeText('infostand.pet.text.happiness') }</Text>
|
||||
<Text variant="white" small truncate>{ LocalizeText('infostand.pet.text.wellbeing') }</Text>
|
||||
<Base fullWidth overflow="hidden" position="relative" className="bg-light-dark rounded">
|
||||
<Flex fit center position="absolute">
|
||||
<Text variant="white" small>{ avatarInfo.happyness + '/' + avatarInfo.maximumHappyness }</Text>
|
||||
<Text variant="white" small>{ avatarInfo.dead ? '00:00:00' : ConvertSeconds((remainingTimeToLive == 0 ? avatarInfo.remainingTimeToLive : remainingTimeToLive)).split(':')[1] + ':' + ConvertSeconds((remainingTimeToLive == null || remainingTimeToLive == undefined ? 0 : remainingTimeToLive)).split(':')[2] + ':' + ConvertSeconds((remainingTimeToLive == null || remainingTimeToLive == undefined ? 0 : remainingTimeToLive)).split(':')[3] }</Text>
|
||||
</Flex>
|
||||
<Base className="bg-info rounded pet-stats" style={ { width: (avatarInfo.happyness / avatarInfo.maximumHappyness) * 100 + '%' } } />
|
||||
<Base className="bg-success rounded pet-stats" style={ { width: avatarInfo.dead ? '0' : Math.round((avatarInfo.maximumTimeToLive * 100) / (remainingTimeToLive)).toString() } } />
|
||||
</Base>
|
||||
</Column>
|
||||
<br /><br />
|
||||
<br /><br />
|
||||
{ remainingGrowTime != 0 && remainingGrowTime > 0 &&
|
||||
<Column alignItems="center" gap={ 1 }>
|
||||
<Text variant="white" small truncate>{ LocalizeText('infostand.pet.text.growth') }</Text> <br />
|
||||
<LayoutCounterTimeView className="top-2 end-2" day={ ConvertSeconds(remainingGrowTime).split(':')[0] } hour={ ConvertSeconds(remainingGrowTime).split(':')[1] } minutes={ ConvertSeconds(remainingGrowTime).split(':')[2] } seconds={ ConvertSeconds(remainingGrowTime).split(':')[3] } />
|
||||
</Column> }
|
||||
<br /><br />
|
||||
<br /><br />
|
||||
<Column alignItems="center" gap={ 1 }>
|
||||
<Text variant="white" small truncate>{ LocalizeText('infostand.pet.text.experience') }</Text>
|
||||
<Base fullWidth overflow="hidden" position="relative" className="bg-light-dark rounded">
|
||||
<Flex fit center position="absolute">
|
||||
<Text variant="white" small>{ avatarInfo.experience + '/' + avatarInfo.levelExperienceGoal }</Text>
|
||||
</Flex>
|
||||
<Base className="bg-purple rounded pet-stats" style={ { width: (avatarInfo.experience / avatarInfo.levelExperienceGoal) * 100 + '%' } } />
|
||||
</Base>
|
||||
</Column>
|
||||
<Column alignItems="center" gap={ 1 }>
|
||||
<Text variant="white" small truncate>{ LocalizeText('infostand.pet.text.energy') }</Text>
|
||||
<Base fullWidth overflow="hidden" position="relative" className="bg-light-dark rounded">
|
||||
<Flex fit center position="absolute">
|
||||
<Text variant="white" small>{ avatarInfo.energy + '/' + avatarInfo.maximumEnergy }</Text>
|
||||
</Flex>
|
||||
<Base className="bg-success rounded pet-stats" style={ { width: (avatarInfo.energy / avatarInfo.maximumEnergy) * 100 + '%' } } />
|
||||
</Base>
|
||||
<Text variant="white" small truncate>{ LocalizeText('Nivel de rareza:') }</Text>
|
||||
<LayoutRarityLevelView className="top-2 end-2" level={ avatarInfo.rarityLevel } />
|
||||
</Column>
|
||||
<br /><br />
|
||||
<Text variant="white" small wrap>{ LocalizeText('pet.age', [ 'age' ], [ avatarInfo.age.toString() ]) }</Text>
|
||||
<hr className="m-0" />
|
||||
</Column>
|
||||
</Flex>
|
||||
<hr className="m-0" />
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
{ avatarInfo.petType !== PetType.MONSTERPLANT &&
|
||||
<Text variant="white" small wrap>{ LocalizeText('infostand.text.petrespect', [ 'count' ], [ avatarInfo.respect.toString() ]) }</Text>
|
||||
}
|
||||
<Text variant="white" small wrap>{ LocalizeText('pet.age', [ 'age' ], [ avatarInfo.age.toString() ]) }</Text>
|
||||
<hr className="m-0" />
|
||||
</Column>
|
||||
</> }
|
||||
{ (avatarInfo.petType !== PetType.MONSTERPLANT) &&
|
||||
<>
|
||||
<Column gap={ 1 }>
|
||||
<Flex gap={ 1 }>
|
||||
<Column fullWidth overflow="hidden" className="body-image pet p-1">
|
||||
<LayoutPetImageView figure={ avatarInfo.petFigure } posture={ avatarInfo.posture } direction={ 4 } />
|
||||
</Column>
|
||||
<Column grow gap={ 1 }>
|
||||
<Text variant="white" center small wrap>{ LocalizeText('pet.level', [ 'level', 'maxlevel' ], [ avatarInfo.level.toString(), avatarInfo.maximumLevel.toString() ]) }</Text>
|
||||
<Column alignItems="center" gap={ 1 }>
|
||||
<Text variant="white" small truncate>{ LocalizeText('infostand.pet.text.happiness') }</Text>
|
||||
<Base fullWidth overflow="hidden" position="relative" className="bg-light-dark rounded">
|
||||
<Flex fit center position="absolute">
|
||||
<Text variant="white" small>{ avatarInfo.happyness + '/' + avatarInfo.maximumHappyness }</Text>
|
||||
</Flex>
|
||||
<Base className="bg-info rounded pet-stats" style={ { width: (avatarInfo.happyness / avatarInfo.maximumHappyness) * 100 + '%' } } />
|
||||
</Base>
|
||||
</Column>
|
||||
<Column alignItems="center" gap={ 1 }>
|
||||
<Text variant="white" small truncate>{ LocalizeText('infostand.pet.text.experience') }</Text>
|
||||
<Base fullWidth overflow="hidden" position="relative" className="bg-light-dark rounded">
|
||||
<Flex fit center position="absolute">
|
||||
<Text variant="white" small>{ avatarInfo.experience + '/' + avatarInfo.levelExperienceGoal }</Text>
|
||||
</Flex>
|
||||
<Base className="bg-purple rounded pet-stats" style={ { width: (avatarInfo.experience / avatarInfo.levelExperienceGoal) * 100 + '%' } } />
|
||||
</Base>
|
||||
</Column>
|
||||
<Column alignItems="center" gap={ 1 }>
|
||||
<Text variant="white" small truncate>{ LocalizeText('infostand.pet.text.energy') }</Text>
|
||||
<Base fullWidth overflow="hidden" position="relative" className="bg-light-dark rounded">
|
||||
<Flex fit center position="absolute">
|
||||
<Text variant="white" small>{ avatarInfo.energy + '/' + avatarInfo.maximumEnergy }</Text>
|
||||
</Flex>
|
||||
<Base className="bg-success rounded pet-stats" style={ { width: (avatarInfo.energy / avatarInfo.maximumEnergy) * 100 + '%' } } />
|
||||
</Base>
|
||||
</Column>
|
||||
</Column>
|
||||
</Flex>
|
||||
<hr className="m-0" />
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
{ (avatarInfo.petType !== PetType.MONSTERPLANT) &&
|
||||
<Text variant="white" small wrap>{ LocalizeText('infostand.text.petrespect', [ 'count' ], [ avatarInfo.respect.toString() ]) }</Text> }
|
||||
<Text variant="white" small wrap>{ LocalizeText('pet.age', [ 'age' ], [ avatarInfo.age.toString() ]) }</Text>
|
||||
<hr className="m-0" />
|
||||
</Column>
|
||||
</> }
|
||||
<Column gap={ 1 }>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<UserProfileIconView userId={ avatarInfo.ownerId } />
|
||||
@ -128,11 +193,11 @@ export const InfoStandWidgetPetView: FC<InfoStandWidgetPetViewProps> = props =>
|
||||
<Button variant="dark" onClick={ event => processButtonAction('train') }>
|
||||
{ LocalizeText('infostand.button.train') }
|
||||
</Button> }
|
||||
{ !avatarInfo.dead && ((avatarInfo.energy / avatarInfo.maximumEnergy) < 0.98) && avatarInfo.petType === PetType.MONSTERPLANT &&
|
||||
{ !avatarInfo.dead && ((avatarInfo.energy / avatarInfo.maximumEnergy) < 0.98) && (avatarInfo.petType === PetType.MONSTERPLANT) &&
|
||||
<Button variant="dark" onClick={ event => processButtonAction('treat') }>
|
||||
{ LocalizeText('infostand.button.pettreat') }
|
||||
</Button> }
|
||||
{ roomSession?.isRoomOwner && avatarInfo.petType === PetType.MONSTERPLANT &&
|
||||
{ roomSession?.isRoomOwner && (avatarInfo.petType === PetType.MONSTERPLANT) &&
|
||||
<Button variant="dark" onClick={ event => processButtonAction('compost') }>
|
||||
{ LocalizeText('infostand.button.compost') }
|
||||
</Button> }
|
||||
|
Loading…
Reference in New Issue
Block a user