mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-31 10:22:36 +01:00
Merge remote-tracking branch 'origin/dev' into @feature/room-tools
This commit is contained in:
commit
5403b176e2
@ -2,6 +2,7 @@
|
||||
"socket.url": "wss://ws.nitrots.co:2096",
|
||||
"asset.url": "https://nitro.nitrots.co",
|
||||
"image.library.url": "https://swf.nitrots.co/c_images/",
|
||||
"internal.samples.url": "",
|
||||
"external.samples.url": "https://swf.nitrots.co/dcr/hof_furni/mp3/sound_machine_sample_%sample%.mp3",
|
||||
"image.library.notifications.url": "${image.library.url}notifications/%image%.png",
|
||||
"achievements.images.url": "${image.library.url}Quests/%image%.png",
|
||||
|
@ -103,7 +103,7 @@ export const FriendListReducer: Reducer<IFriendListState, IFriendListAction> = (
|
||||
|
||||
for(const friend of update.addedFriends) processUpdate(friend);
|
||||
|
||||
for(const friend of update.addedFriends) processUpdate(friend);
|
||||
for(const friend of update.updatedFriends) processUpdate(friend);
|
||||
|
||||
for(const removedFriendId of update.removedFriendIds)
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { FollowFriendComposer, MouseEventType, Nitro } from 'nitro-renderer';
|
||||
import { FC, useEffect, useRef, useState } from 'react';
|
||||
import { FollowFriendComposer, MouseEventType } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { GetConnection } from '../../../../api';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView';
|
||||
import { FriendBarItemViewProps } from './FriendBarItemView.types';
|
||||
@ -7,15 +8,15 @@ import { FriendBarItemViewProps } from './FriendBarItemView.types';
|
||||
export const FriendBarItemView: FC<FriendBarItemViewProps> = props =>
|
||||
{
|
||||
const { friend = null } = props;
|
||||
const [isVisible, setVisible] = useState(false);
|
||||
|
||||
const toggleVisible = () => setVisible(prevCheck => !prevCheck);
|
||||
|
||||
const [ isVisible, setVisible ] = useState(false);
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
useEffect(() =>
|
||||
const followFriend = useCallback(() =>
|
||||
{
|
||||
function onClick(event: MouseEvent): void
|
||||
GetConnection().send(new FollowFriendComposer(friend.id));
|
||||
}, [ friend ]);
|
||||
|
||||
const onClick = useCallback((event: MouseEvent) =>
|
||||
{
|
||||
const element = elementRef.current;
|
||||
|
||||
@ -23,22 +24,17 @@ export const FriendBarItemView: FC<FriendBarItemViewProps> = props =>
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
document.addEventListener(MouseEventType.MOUSE_CLICK, onClick);
|
||||
|
||||
return () =>
|
||||
{
|
||||
document.removeEventListener(MouseEventType.MOUSE_CLICK, onClick);
|
||||
}
|
||||
}, [ elementRef, setVisible ]);
|
||||
|
||||
|
||||
const followFriend = () =>
|
||||
{
|
||||
|
||||
Nitro.instance.communication.connection.send(new FollowFriendComposer(friend.id));
|
||||
}
|
||||
}, [ onClick ]);
|
||||
|
||||
if(!friend)
|
||||
{
|
||||
@ -51,16 +47,17 @@ export const FriendBarItemView: FC<FriendBarItemViewProps> = props =>
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref={ elementRef } className={"btn btn-success friend-bar-item " + (isVisible ? "friend-bar-item-active" : "")} onClick={ event => toggleVisible()}>
|
||||
<div ref={ elementRef } className={"btn btn-success friend-bar-item " + (isVisible ? "friend-bar-item-active" : "")} onClick={ event => setVisible(prevValue => !prevValue) }>
|
||||
<div className="friend-bar-item-head position-absolute">
|
||||
<AvatarImageView headOnly={true} figure={friend.figure} direction={2} />
|
||||
<AvatarImageView headOnly={ true } figure={ friend.figure } direction={ 2 } />
|
||||
</div>
|
||||
<div className="text-truncate">{friend.name}</div>
|
||||
{isVisible && <div className="d-flex justify-content-between">
|
||||
<div className="text-truncate">{ friend.name }</div>
|
||||
{ isVisible &&
|
||||
<div className="d-flex justify-content-between">
|
||||
<i className="icon icon-fb-chat cursor-pointer" />
|
||||
{friend.followingAllowed && <i onClick={ event => followFriend() } className="icon icon-fb-visit cursor-pointer" />}
|
||||
{ friend.followingAllowed && <i onClick={ followFriend } className="icon icon-fb-visit cursor-pointer" /> }
|
||||
<i className="icon icon-fb-profile cursor-pointer" />
|
||||
</div>}
|
||||
</div> }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -8,6 +8,12 @@ export const FriendBarView: FC<FriendBarViewProps> = props =>
|
||||
const { friendListState = null } = useFriendListContext();
|
||||
const { friends = null } = friendListState;
|
||||
const [ indexOffset, setIndexOffset ] = useState(0);
|
||||
const [ maxDisplayCount, setMaxDisplayCount ] = useState(3);
|
||||
|
||||
const onlineFriends = useMemo(() =>
|
||||
{
|
||||
return friends.filter(friend => friend.online);
|
||||
}, [ friends ]);
|
||||
|
||||
const canDecreaseIndex = useMemo(() =>
|
||||
{
|
||||
@ -18,20 +24,21 @@ export const FriendBarView: FC<FriendBarViewProps> = props =>
|
||||
|
||||
const canIncreaseIndex = useMemo(() =>
|
||||
{
|
||||
if(indexOffset === (friends.length - 1)) return false;
|
||||
if((onlineFriends.length <= maxDisplayCount) || (indexOffset === (onlineFriends.length - 1))) return false;
|
||||
|
||||
return true;
|
||||
}, [ indexOffset, friends ]);
|
||||
}, [ maxDisplayCount, indexOffset, onlineFriends ]);
|
||||
|
||||
return (
|
||||
<div className="d-flex friend-bar align-items-center">
|
||||
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={!canDecreaseIndex} onClick={event => setIndexOffset(indexOffset - 1)}>
|
||||
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={ !canDecreaseIndex } onClick={ event => setIndexOffset(indexOffset - 1) }>
|
||||
<i className="fas fa-chevron-left" />
|
||||
</button>
|
||||
<FriendBarItemView friend={ (friends[ indexOffset ] || null) } />
|
||||
<FriendBarItemView friend={ (friends[ indexOffset + 1 ] || null) } />
|
||||
<FriendBarItemView friend={ (friends[ indexOffset + 2 ] || null) } />
|
||||
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={!canIncreaseIndex} onClick={event => setIndexOffset(indexOffset + 1)}>
|
||||
{ Array.from(Array(maxDisplayCount), (e, i) =>
|
||||
{
|
||||
return <FriendBarItemView friend={ (onlineFriends[ indexOffset + i ] || null) } />;
|
||||
}) }
|
||||
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={ !canIncreaseIndex } onClick={ event => setIndexOffset(indexOffset + 1) }>
|
||||
<i className="fas fa-chevron-right" />
|
||||
</button>
|
||||
</div>
|
||||
|
@ -8,9 +8,9 @@ export const InventoryActiveBadgeResultsView: FC<InventoryActiveBadgeResultsView
|
||||
|
||||
return (
|
||||
<div className="row row-cols-3 align-content-start g-0">
|
||||
{ badges && (badges.length > 0) && badges.map((code, index) =>
|
||||
{ badges && (badges.length > 0) && badges.map(code =>
|
||||
{
|
||||
return <InventoryBadgeItemView key={ index } badge={ code } />
|
||||
return <InventoryBadgeItemView key={ code } badge={ code } />
|
||||
}) }
|
||||
</div>
|
||||
);
|
||||
|
@ -9,11 +9,11 @@ export const InventoryBadgeResultsView: FC<InventoryBadgeResultsViewProps> = pro
|
||||
return (
|
||||
<div className="h-100 overflow-hidden">
|
||||
<div className="row row-cols-5 align-content-start g-0 w-100 h-100 overflow-auto">
|
||||
{ badges && (badges.length > 0) && badges.map((code, index) =>
|
||||
{ badges && (badges.length > 0) && badges.map(code =>
|
||||
{
|
||||
if(activeBadges.indexOf(code) >= 0) return null;
|
||||
|
||||
return <InventoryBadgeItemView key={ index } badge={ code } />
|
||||
return <InventoryBadgeItemView key={ code } badge={ code } />
|
||||
}) }
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,9 +9,9 @@ export const InventoryBotResultsView: FC<InventoryBotResultsViewProps> = props =
|
||||
return (
|
||||
<div className="h-100 overflow-hidden">
|
||||
<div className="row row-cols-5 align-content-start g-0 w-100 h-100 overflow-auto">
|
||||
{ botItems && (botItems.length > 0) && botItems.map((item, index) =>
|
||||
{ botItems && (botItems.length > 0) && botItems.map(item =>
|
||||
{
|
||||
return <InventoryBotItemView key={ index } botItem={ item } />
|
||||
return <InventoryBotItemView key={ item.id } botItem={ item } />
|
||||
}) }
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,9 +9,9 @@ export const InventoryPetResultsView: FC<InventoryPetResultsViewProps> = props =
|
||||
return (
|
||||
<div className="h-100 overflow-hidden">
|
||||
<div className="row row-cols-5 align-content-start g-0 w-100 h-100 overflow-auto">
|
||||
{ petItems && (petItems.length > 0) && petItems.map((item, index) =>
|
||||
{ petItems && (petItems.length > 0) && petItems.map(item =>
|
||||
{
|
||||
return <InventoryPetItemView key={ index } petItem={ item } />
|
||||
return <InventoryPetItemView key={ item.id } petItem={ item } />
|
||||
}) }
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { UserCreditsEvent, UserCurrencyEvent, UserCurrencyUpdateEvent } from 'nitro-renderer';
|
||||
import { UserCreditsEvent, UserCurrencyEvent, UserCurrencyUpdateEvent, UserSubscriptionEvent } from 'nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||
import { Currency } from './common/Currency';
|
||||
@ -48,9 +48,27 @@ export const PurseMessageHandler: FC<PurseMessageHandlerProps> = props =>
|
||||
});
|
||||
}, [ dispatchPurseState ]);
|
||||
|
||||
const onUserSubscriptionEvent = useCallback((event: UserSubscriptionEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
switch(parser.name)
|
||||
{
|
||||
case 'habbo_club':
|
||||
dispatchPurseState({
|
||||
type: PurseActions.SET_CLUB_SUBSCRIPTION,
|
||||
payload: {
|
||||
clubSubscription: parser
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}, [ dispatchPurseState ]);
|
||||
|
||||
CreateMessageHook(UserCreditsEvent, onUserCreditsEvent);
|
||||
CreateMessageHook(UserCurrencyEvent, onUserCurrencyEvent);
|
||||
CreateMessageHook(UserCurrencyUpdateEvent, onUserCurrencyUpdateEvent);
|
||||
CreateMessageHook(UserSubscriptionEvent, onUserSubscriptionEvent);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { UserSubscriptionParser } from 'nitro-renderer';
|
||||
import { Reducer } from 'react';
|
||||
import { Currency } from '../common/Currency';
|
||||
|
||||
export interface IPurseState
|
||||
{
|
||||
currencies: Currency[];
|
||||
clubSubscription: UserSubscriptionParser;
|
||||
}
|
||||
|
||||
export interface IPurseAction
|
||||
@ -12,6 +14,7 @@ export interface IPurseAction
|
||||
payload: {
|
||||
currency?: Currency;
|
||||
currencies?: Currency[];
|
||||
clubSubscription?: UserSubscriptionParser;
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,10 +22,12 @@ export class PurseActions
|
||||
{
|
||||
public static SET_CURRENCY: string = 'PA_SET_CURRENCY';
|
||||
public static SET_CURRENCIES: string = 'PA_SET_CURRENCIES';
|
||||
public static SET_CLUB_SUBSCRIPTION: string = 'PA_SET_CLUB_SUBSCRIPTION';
|
||||
}
|
||||
|
||||
export const initialPurse: IPurseState = {
|
||||
currencies: []
|
||||
currencies: [],
|
||||
clubSubscription: null
|
||||
}
|
||||
|
||||
export const PurseReducer: Reducer<IPurseState, IPurseAction> = (state, action) =>
|
||||
@ -34,7 +39,7 @@ export const PurseReducer: Reducer<IPurseState, IPurseAction> = (state, action)
|
||||
|
||||
let didSet = false;
|
||||
|
||||
const currencies = state.currencies.map((existing, index) =>
|
||||
const currencies = state.currencies.map(existing =>
|
||||
{
|
||||
if(existing.type !== updated.type) return existing;
|
||||
|
||||
@ -50,7 +55,7 @@ export const PurseReducer: Reducer<IPurseState, IPurseAction> = (state, action)
|
||||
case PurseActions.SET_CURRENCIES: {
|
||||
const updated = action.payload.currencies;
|
||||
|
||||
const currencies = state.currencies.filter((existing, index) =>
|
||||
const currencies = state.currencies.filter(existing =>
|
||||
{
|
||||
if(existing.type !== -1) return null;
|
||||
|
||||
@ -61,6 +66,11 @@ export const PurseReducer: Reducer<IPurseState, IPurseAction> = (state, action)
|
||||
|
||||
return { ...state, currencies };
|
||||
}
|
||||
case PurseActions.SET_CLUB_SUBSCRIPTION: {
|
||||
const clubSubscription = action.payload.clubSubscription;
|
||||
|
||||
return { ...state, clubSubscription };
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@ -122,9 +122,9 @@ export const FurnitureStickieView: FC<FurnitureStickieViewProps> = props =>
|
||||
{ stickieData.canModify &&
|
||||
<>
|
||||
<div className="nitro-stickie-image stickie-trash header-trash" onClick={ event => processAction('trash') }></div>
|
||||
{ STICKIE_COLORS.map((color, index) =>
|
||||
{ STICKIE_COLORS.map(color =>
|
||||
{
|
||||
return <div className="stickie-color ms-1" key={ index } onClick={ event => processAction('changeColor', color) } style={ {backgroundColor: ColorUtils.makeColorHex(color) } } />
|
||||
return <div key={ color } className="stickie-color ms-1" onClick={ event => processAction('changeColor', color) } style={ {backgroundColor: ColorUtils.makeColorHex(color) } } />
|
||||
})}
|
||||
</> }
|
||||
</div>
|
||||
|
@ -24,9 +24,9 @@ export const InfoStandWidgetBotView: FC<InfoStandWidgetBotViewProps> = props =>
|
||||
<AvatarImageView figure={ botData.figure } direction={ 4 } />
|
||||
</div>
|
||||
<div className="w-100 d-flex justify-content-center align-items-center">
|
||||
{ (botData.badges.length > 0) && botData.badges.map((result, index) =>
|
||||
{ (botData.badges.length > 0) && botData.badges.map(result =>
|
||||
{
|
||||
return <BadgeImageView key={ index } badgeCode={ result } />;
|
||||
return <BadgeImageView key={ result } badgeCode={ result } />;
|
||||
}) }
|
||||
</div>
|
||||
</div>
|
||||
|
@ -36,9 +36,9 @@ export const InfoStandWidgetRentableBotView: FC<InfoStandWidgetRentableBotViewPr
|
||||
<AvatarImageView figure={ rentableBotData.figure } direction={ 4 } />
|
||||
</div>
|
||||
<div className="w-100 d-flex justify-content-center align-items-center">
|
||||
{ (rentableBotData.badges.length > 0) && rentableBotData.badges.map((result, index) =>
|
||||
{ (rentableBotData.badges.length > 0) && rentableBotData.badges.map(result =>
|
||||
{
|
||||
return <BadgeImageView key={ index } badgeCode={ result } />;
|
||||
return <BadgeImageView key={ result } badgeCode={ result } />;
|
||||
}) }
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,9 +26,9 @@ export const WiredConditionActorHasHandItemView: FC<{}> = props =>
|
||||
<div className="form-group">
|
||||
<label className="fw-bold">{ LocalizeText('wiredfurni.params.handitem') }</label>
|
||||
<select className="form-select form-select-sm" value={ handItemId } onChange={ event => setHandItemId(parseInt(event.target.value)) }>
|
||||
{ allowedHanditemIds.map((value, index) =>
|
||||
{ allowedHanditemIds.map(value =>
|
||||
{
|
||||
return <option key={ index } value={ value }>{ LocalizeText(`handitem${ value }`) }</option>
|
||||
return <option key={ value } value={ value }>{ LocalizeText(`handitem${ value }`) }</option>
|
||||
}) }
|
||||
</select>
|
||||
</div>
|
||||
|
@ -25,10 +25,10 @@ export const WiredConditionActorIsTeamMemberView: FC<{}> = props =>
|
||||
<WiredConditionBaseView requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
|
||||
<div className="form-group">
|
||||
<label className="fw-bold">{ LocalizeText('wiredfurni.params.team') }</label>
|
||||
{ teamIds.map((value, index) =>
|
||||
{ teamIds.map(value =>
|
||||
{
|
||||
return (
|
||||
<div key={ index } className="form-check">
|
||||
<div key={ value } className="form-check">
|
||||
<input className="form-check-input" type="radio" name="selectedTeam" id={ `selectedTeam${ value }` } checked={ (selectedTeam === value) } onChange={ event => setSelectedTeam(value) } />
|
||||
<label className="form-check-label" htmlFor={ `selectedTeam${ value }` }>
|
||||
{ LocalizeText(`wiredfurni.params.team.${ value }`) }
|
||||
|
Loading…
x
Reference in New Issue
Block a user