mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
132 lines
7.8 KiB
TypeScript
132 lines
7.8 KiB
TypeScript
import { HabboSearchComposer, HabboSearchResultData, HabboSearchResultEvent } from '@nitrots/nitro-renderer';
|
|
import { FC, useEffect, useState } from 'react';
|
|
import { LocalizeText, OpenMessengerChat, SendMessageComposer } from '../../../../api';
|
|
import { Column, LayoutAvatarImageView, NitroCardAccordionItemView, NitroCardAccordionSetView, NitroCardAccordionSetViewProps, Text, UserProfileIconView } from '../../../../common';
|
|
import { useFriends, useMessageEvent } from '../../../../hooks';
|
|
import { resolveAvatarFigure } from './resolveAvatarFigure';
|
|
import { resolveAvatarGender } from './resolveAvatarGender';
|
|
|
|
interface FriendsSearchViewProps extends NitroCardAccordionSetViewProps
|
|
{
|
|
|
|
}
|
|
|
|
export const FriendsSearchView: FC<FriendsSearchViewProps> = props =>
|
|
{
|
|
const { ...rest } = props;
|
|
const [ searchValue, setSearchValue ] = useState('');
|
|
const [ friendResults, setFriendResults ] = useState<HabboSearchResultData[]>(null);
|
|
const [ otherResults, setOtherResults ] = useState<HabboSearchResultData[]>(null);
|
|
const { canRequestFriend = null, requestFriend = null } = useFriends();
|
|
|
|
const getSearchResultFigure = (result: HabboSearchResultData) =>
|
|
{
|
|
if(!result) return null;
|
|
|
|
const typedResult = (result as HabboSearchResultData & { figureString?: string; avatarFigure?: string; figure?: string; avatarFigureString?: string });
|
|
|
|
return typedResult.figureString || typedResult.avatarFigure || typedResult.figure || typedResult.avatarFigureString || null;
|
|
};
|
|
|
|
const getSearchResultGender = (result: HabboSearchResultData) =>
|
|
{
|
|
const typedResult = (result as HabboSearchResultData & { gender?: string | number; avatarGender?: string | number });
|
|
|
|
return resolveAvatarGender(typedResult.avatarGender ?? typedResult.gender);
|
|
};
|
|
|
|
useMessageEvent<HabboSearchResultEvent>(HabboSearchResultEvent, event =>
|
|
{
|
|
const parser = event.getParser();
|
|
|
|
setFriendResults(parser.friends);
|
|
setOtherResults(parser.others);
|
|
});
|
|
|
|
useEffect(() =>
|
|
{
|
|
if(!searchValue || !searchValue.length) return;
|
|
|
|
const timeout = setTimeout(() =>
|
|
{
|
|
if(!searchValue || !searchValue.length) return;
|
|
|
|
SendMessageComposer(new HabboSearchComposer(searchValue));
|
|
}, 500);
|
|
|
|
return () => clearTimeout(timeout);
|
|
}, [ searchValue ]);
|
|
|
|
return (
|
|
<NitroCardAccordionSetView { ...rest }>
|
|
<input className="search-input form-control form-control-sm w-full rounded-0" maxLength={ 50 } placeholder={ LocalizeText('generic.search') } type="text" value={ searchValue } onChange={ event => setSearchValue(event.target.value) } />
|
|
<div className="flex flex-col">
|
|
{ friendResults &&
|
|
<>
|
|
{ (friendResults.length === 0) &&
|
|
<Text bold small className="px-2 py-1">{ LocalizeText('friendlist.search.nofriendsfound') }</Text> }
|
|
{ (friendResults.length > 0) &&
|
|
<Column gap={ 0 }>
|
|
<Text bold small className="px-2 py-1">{ LocalizeText('friendlist.search.friendscaption', [ 'cnt' ], [ friendResults.length.toString() ]) }</Text>
|
|
<hr className="mx-2 mt-0 mb-1 text-black" />
|
|
<Column gap={ 0 }>
|
|
{ friendResults.map(result =>
|
|
{
|
|
return (
|
|
<NitroCardAccordionItemView key={ result.avatarId } className="friends-list-item px-2 py-1" justifyContent="between">
|
|
<div className="friends-list-user">
|
|
<div className="friends-list-avatar">
|
|
<LayoutAvatarImageView figure={ resolveAvatarFigure(getSearchResultFigure(result), getSearchResultGender(result)) } gender={ getSearchResultGender(result) } headOnly={ true } direction={ 2 } />
|
|
</div>
|
|
<div>
|
|
<UserProfileIconView userId={ result.avatarId } />
|
|
</div>
|
|
<div className="friends-list-name">{ result.avatarName }</div>
|
|
</div>
|
|
<div className="flex items-center gap-1">
|
|
{ result.isAvatarOnline &&
|
|
<div className="nitro-friends-spritesheet icon-chat cursor-pointer" title={ LocalizeText('friendlist.tip.im') } onClick={ event => OpenMessengerChat(result.avatarId) } /> }
|
|
</div>
|
|
</NitroCardAccordionItemView>
|
|
);
|
|
}) }
|
|
</Column>
|
|
</Column> }
|
|
</> }
|
|
{ otherResults &&
|
|
<>
|
|
{ (otherResults.length === 0) &&
|
|
<Text bold small className="px-2 py-1">{ LocalizeText('friendlist.search.noothersfound') }</Text> }
|
|
{ (otherResults.length > 0) &&
|
|
<Column gap={ 0 }>
|
|
<Text bold small className="px-2 py-1">{ LocalizeText('friendlist.search.otherscaption', [ 'cnt' ], [ otherResults.length.toString() ]) }</Text>
|
|
<hr className="mx-2 mt-0 mb-1 text-black" />
|
|
<Column gap={ 0 }>
|
|
{ otherResults.map(result =>
|
|
{
|
|
return (
|
|
<NitroCardAccordionItemView key={ result.avatarId } className="friends-list-item px-2 py-1" justifyContent="between">
|
|
<div className="friends-list-user">
|
|
<div className="friends-list-avatar">
|
|
<LayoutAvatarImageView figure={ resolveAvatarFigure(getSearchResultFigure(result), getSearchResultGender(result)) } gender={ getSearchResultGender(result) } headOnly={ true } direction={ 2 } />
|
|
</div>
|
|
<div>
|
|
<UserProfileIconView userId={ result.avatarId } />
|
|
</div>
|
|
<div className="friends-list-name">{ result.avatarName }</div>
|
|
</div>
|
|
<div className="flex items-center gap-1">
|
|
{ canRequestFriend(result.avatarId) &&
|
|
<div className="nitro-friends-spritesheet icon-add cursor-pointer" title={ LocalizeText('friendlist.tip.addfriend') } onClick={ event => requestFriend(result.avatarId, result.avatarName) } /> }
|
|
</div>
|
|
</NitroCardAccordionItemView>
|
|
);
|
|
}) }
|
|
</Column>
|
|
</Column> }
|
|
</> }
|
|
</div>
|
|
</NitroCardAccordionSetView>
|
|
);
|
|
};
|