mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-02-20 02:32:37 +01:00
WIP: Friend List
This commit is contained in:
parent
6f0ac2e7e8
commit
4e4a3fb14f
7
src/events/friend-list/FriendListEvent.ts
Normal file
7
src/events/friend-list/FriendListEvent.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { NitroEvent } from 'nitro-renderer';
|
||||||
|
|
||||||
|
export class FriendListEvent extends NitroEvent
|
||||||
|
{
|
||||||
|
public static SHOW_FRIEND_LIST: string = 'IE_SHOW_FRIEND_LIST';
|
||||||
|
public static TOGGLE_FRIEND_LIST: string = 'IE_TOGGLE_FRIEND_LIST';
|
||||||
|
}
|
1
src/events/friend-list/index.ts
Normal file
1
src/events/friend-list/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './FriendListEvent';
|
@ -1,3 +1,4 @@
|
|||||||
export * from './catalog';
|
export * from './catalog';
|
||||||
|
export * from './friend-list';
|
||||||
export * from './inventory';
|
export * from './inventory';
|
||||||
export * from './navigator';
|
export * from './navigator';
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
@import './catalog/CatalogView';
|
@import './catalog/CatalogView';
|
||||||
@import './hotel-view/HotelView';
|
@import './hotel-view/HotelView';
|
||||||
@import './inventory/InventoryView';
|
@import './inventory/InventoryView';
|
||||||
|
@import './friend-list/FriendListView';
|
||||||
@import './loading/LoadingView';
|
@import './loading/LoadingView';
|
||||||
@import './main/MainView';
|
@import './main/MainView';
|
||||||
@import './navigator/NavigatorView';
|
@import './navigator/NavigatorView';
|
||||||
|
18
src/views/friend-list/FriendListMessageHandler.tsx
Normal file
18
src/views/friend-list/FriendListMessageHandler.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { FriendListMessageHandlerProps } from './FriendListMessageHandler.types';
|
||||||
|
|
||||||
|
export function FriendListMessageHandler(props: FriendListMessageHandlerProps): JSX.Element
|
||||||
|
{
|
||||||
|
const { } = props;
|
||||||
|
|
||||||
|
/*const onUserInfoEvent = useCallback((event: UserInfoEvent) =>
|
||||||
|
{
|
||||||
|
//const parser = event.getParser();
|
||||||
|
|
||||||
|
SendMessageHook(new NavigatorCategoriesComposer());
|
||||||
|
SendMessageHook(new NavigatorSettingsComposer());
|
||||||
|
}, []);*/
|
||||||
|
|
||||||
|
//CreateMessageHook(UserInfoEvent, onUserInfoEvent);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
2
src/views/friend-list/FriendListMessageHandler.types.ts
Normal file
2
src/views/friend-list/FriendListMessageHandler.types.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export interface FriendListMessageHandlerProps
|
||||||
|
{}
|
3
src/views/friend-list/FriendListView.scss
Normal file
3
src/views/friend-list/FriendListView.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.nitro-friend-list {
|
||||||
|
width: 250px;
|
||||||
|
}
|
63
src/views/friend-list/FriendListView.tsx
Normal file
63
src/views/friend-list/FriendListView.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import React, { FC, useCallback, useEffect, useState } from 'react';
|
||||||
|
import { FriendListEvent } from '../../events';
|
||||||
|
import { DraggableWindow } from '../../hooks/draggable-window/DraggableWindow';
|
||||||
|
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
|
import { LocalizeText } from '../../utils/LocalizeText';
|
||||||
|
import { FriendListMessageHandler } from './FriendListMessageHandler';
|
||||||
|
import { FriendListTabs, FriendListViewProps, IFriendListContext } from './FriendListView.types';
|
||||||
|
import { FriendListTabsContentView } from './tabs-content/FriendListTabsContentView';
|
||||||
|
import { FriendListTabsSelectorView } from './tabs-selector/FriendListTabsSelectorView';
|
||||||
|
|
||||||
|
export const FriendListContext = React.createContext<IFriendListContext>(null);
|
||||||
|
|
||||||
|
export const FriendListView: FC<FriendListViewProps> = props =>
|
||||||
|
{
|
||||||
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
|
const [ currentTab, setCurrentTab ] = useState<string>(null);
|
||||||
|
const [ tabs, setTabs ] = useState<string[]>([
|
||||||
|
FriendListTabs.FRIENDS, FriendListTabs.REQUESTS, FriendListTabs.SEARCH
|
||||||
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentTab(tabs[0]);
|
||||||
|
}, [ tabs ]);
|
||||||
|
|
||||||
|
const onFriendListEvent = useCallback((event: FriendListEvent) =>
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case FriendListEvent.SHOW_FRIEND_LIST:
|
||||||
|
setIsVisible(true);
|
||||||
|
return;
|
||||||
|
case FriendListEvent.TOGGLE_FRIEND_LIST:
|
||||||
|
setIsVisible(value => !value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useUiEvent(FriendListEvent.SHOW_FRIEND_LIST, onFriendListEvent);
|
||||||
|
useUiEvent(FriendListEvent.TOGGLE_FRIEND_LIST, onFriendListEvent);
|
||||||
|
|
||||||
|
function hideFriendList(): void
|
||||||
|
{
|
||||||
|
setIsVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FriendListContext.Provider value={{ currentTab: currentTab, onSetCurrentTab: setCurrentTab }}>
|
||||||
|
<FriendListMessageHandler />
|
||||||
|
{ isVisible && <DraggableWindow handle=".drag-handler">
|
||||||
|
<div className="nitro-friend-list d-flex flex-column bg-primary border border-black shadow rounded">
|
||||||
|
<div className="drag-handler d-flex justify-content-between align-items-center px-3 pt-3">
|
||||||
|
<div className="h6 m-0">{ LocalizeText('friendlist.friends') }</div>
|
||||||
|
<button type="button" className="close" onClick={ hideFriendList }>
|
||||||
|
<i className="fas fa-times"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<FriendListTabsSelectorView tabs={ tabs } />
|
||||||
|
<FriendListTabsContentView />
|
||||||
|
</div>
|
||||||
|
</DraggableWindow> }
|
||||||
|
</FriendListContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
15
src/views/friend-list/FriendListView.types.ts
Normal file
15
src/views/friend-list/FriendListView.types.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export interface FriendListViewProps
|
||||||
|
{}
|
||||||
|
|
||||||
|
export interface IFriendListContext
|
||||||
|
{
|
||||||
|
currentTab: string;
|
||||||
|
onSetCurrentTab: (tab: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FriendListTabs
|
||||||
|
{
|
||||||
|
public static readonly FRIENDS: string = 'friendlist.friends';
|
||||||
|
public static readonly REQUESTS: string = 'friendlist.requests';
|
||||||
|
public static readonly SEARCH: string = 'generic.search';
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
import { FC, useContext } from 'react';
|
||||||
|
import { FriendListContext } from '../FriendListView';
|
||||||
|
import { FriendListTabs } from '../FriendListView.types';
|
||||||
|
import { FriendListTabsContentViewProps } from './FriendListTabsContentView.types';
|
||||||
|
import { FriendListTabFriendsView } from './friends/FriendListTabFriendsView';
|
||||||
|
|
||||||
|
export const FriendListTabsContentView: FC<FriendListTabsContentViewProps> = props =>
|
||||||
|
{
|
||||||
|
const friendListContext = useContext(FriendListContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="px-3 pb-3">
|
||||||
|
{ friendListContext && friendListContext.currentTab && friendListContext.currentTab === FriendListTabs.FRIENDS && <FriendListTabFriendsView /> }
|
||||||
|
{ friendListContext && friendListContext.currentTab && friendListContext.currentTab === FriendListTabs.REQUESTS }
|
||||||
|
{ friendListContext && friendListContext.currentTab && friendListContext.currentTab === FriendListTabs.SEARCH }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
export interface FriendListTabsContentViewProps
|
||||||
|
{}
|
@ -0,0 +1,35 @@
|
|||||||
|
import classNames from 'classnames';
|
||||||
|
import { FC, useContext, useState } from 'react';
|
||||||
|
import { FriendListContext } from '../../FriendListView';
|
||||||
|
import { FriendListTabFriendsViewProps } from './FriendListTabFriendsView.types';
|
||||||
|
|
||||||
|
export const FriendListTabFriendsView: FC<FriendListTabFriendsViewProps> = props =>
|
||||||
|
{
|
||||||
|
const friendListContext = useContext(FriendListContext);
|
||||||
|
|
||||||
|
const [ isOnlineFriendsExtended, setIsOnlineFriendsExtended ] = useState(false);
|
||||||
|
const [ isOfflineFriendsExtended, setIsOfflineFriendsExtended ] = useState(false);
|
||||||
|
|
||||||
|
function toggleOnlineFriends(): void
|
||||||
|
{
|
||||||
|
setIsOnlineFriendsExtended(value => !value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleOfflineFriends(): void
|
||||||
|
{
|
||||||
|
setIsOfflineFriendsExtended(value => !value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="d-flex mb-2 small">
|
||||||
|
<i className={ "fas " + classNames({ 'fa-plus': !isOnlineFriendsExtended, 'fa-minus': isOnlineFriendsExtended })} onClick={ toggleOnlineFriends }></i>
|
||||||
|
<div className="align-self-center w-100 ml-2">Friends (0)</div>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex mb-2 small">
|
||||||
|
<i className={ "fas " + classNames({ 'fa-plus': !isOfflineFriendsExtended, 'fa-minus': isOfflineFriendsExtended })} onClick={ toggleOfflineFriends }></i>
|
||||||
|
<div className="align-self-center w-100 ml-2">Offline Friends (0)</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
export interface FriendListTabFriendsViewProps
|
||||||
|
{}
|
@ -0,0 +1,18 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { FriendListTabsSelectorViewProps } from './FriendListTabsSelectorView.types';
|
||||||
|
import { FriendListTabView } from './tab/FriendListTabView';
|
||||||
|
|
||||||
|
export const FriendListTabsSelectorView: FC<FriendListTabsSelectorViewProps> = props =>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<div className="p-3">
|
||||||
|
{ props.tabs &&
|
||||||
|
<div className="btn-group w-100">
|
||||||
|
{ props.tabs.map((tab, index) =>
|
||||||
|
{
|
||||||
|
return <FriendListTabView key={ index } tab={ tab } />
|
||||||
|
}) }
|
||||||
|
</div> }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
export interface FriendListTabsSelectorViewProps
|
||||||
|
{
|
||||||
|
tabs: string[];
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
import classNames from 'classnames';
|
||||||
|
import { FC, useContext } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||||
|
import { FriendListContext } from '../../FriendListView';
|
||||||
|
import { FriendListTabViewProps } from './FriendListTabView.types';
|
||||||
|
|
||||||
|
export const FriendListTabView: FC<FriendListTabViewProps> = props =>
|
||||||
|
{
|
||||||
|
const friendListContext = useContext(FriendListContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button type="button"
|
||||||
|
className={ 'btn btn-secondary btn-sm ' + classNames({ 'active': friendListContext.currentTab === props.tab })}
|
||||||
|
onClick={ () => friendListContext.onSetCurrentTab(props.tab) }>
|
||||||
|
{ LocalizeText(props.tab) }
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
export interface FriendListTabViewProps
|
||||||
|
{
|
||||||
|
tab: string;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
export interface InventoryTabViewProps
|
export interface InventoryTabViewProps
|
||||||
{
|
{
|
||||||
tab?: string;
|
tab: string;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/roo
|
|||||||
import { TransitionAnimation } from '../../transitions/TransitionAnimation';
|
import { TransitionAnimation } from '../../transitions/TransitionAnimation';
|
||||||
import { TransitionAnimationTypes } from '../../transitions/TransitionAnimation.types';
|
import { TransitionAnimationTypes } from '../../transitions/TransitionAnimation.types';
|
||||||
import { CatalogView } from '../catalog/CatalogView';
|
import { CatalogView } from '../catalog/CatalogView';
|
||||||
|
import { FriendListView } from '../friend-list/FriendListView';
|
||||||
import { HotelView } from '../hotel-view/HotelView';
|
import { HotelView } from '../hotel-view/HotelView';
|
||||||
import { InventoryView } from '../inventory/InventoryView';
|
import { InventoryView } from '../inventory/InventoryView';
|
||||||
import { NavigatorView } from '../navigator/NavigatorView';
|
import { NavigatorView } from '../navigator/NavigatorView';
|
||||||
@ -50,6 +51,7 @@ export function MainView(props: MainViewProps): JSX.Element
|
|||||||
<NavigatorView />
|
<NavigatorView />
|
||||||
<InventoryView />
|
<InventoryView />
|
||||||
<CatalogView />
|
<CatalogView />
|
||||||
|
<FriendListView />
|
||||||
<RightSideView />
|
<RightSideView />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { UserInfoEvent } from 'nitro-renderer/src/nitro/communication/messages/incoming/user/data/UserInfoEvent';
|
import { UserInfoEvent } from 'nitro-renderer/src/nitro/communication/messages/incoming/user/data/UserInfoEvent';
|
||||||
import { UserInfoDataParser } from 'nitro-renderer/src/nitro/communication/messages/parser/user/data/UserInfoDataParser';
|
import { UserInfoDataParser } from 'nitro-renderer/src/nitro/communication/messages/parser/user/data/UserInfoDataParser';
|
||||||
import { MouseEvent, useCallback, useState } from 'react';
|
import { MouseEvent, useCallback, useState } from 'react';
|
||||||
import { CatalogEvent, InventoryEvent, NavigatorEvent } from '../../events';
|
import { CatalogEvent, FriendListEvent, InventoryEvent, NavigatorEvent } from '../../events';
|
||||||
import { dispatchUiEvent } from '../../hooks/events/ui/ui-event';
|
import { dispatchUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||||
import { AvatarImageView } from '../avatar-image/AvatarImageView';
|
import { AvatarImageView } from '../avatar-image/AvatarImageView';
|
||||||
@ -39,6 +39,9 @@ export function ToolbarView(props: ToolbarViewProps): JSX.Element
|
|||||||
case ToolbarViewItems.CATALOG_ITEM:
|
case ToolbarViewItems.CATALOG_ITEM:
|
||||||
dispatchUiEvent(new CatalogEvent(CatalogEvent.TOGGLE_CATALOG));
|
dispatchUiEvent(new CatalogEvent(CatalogEvent.TOGGLE_CATALOG));
|
||||||
return;
|
return;
|
||||||
|
case ToolbarViewItems.FRIEND_LIST_ITEM:
|
||||||
|
dispatchUiEvent(new CatalogEvent(FriendListEvent.TOGGLE_FRIEND_LIST));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +70,7 @@ export function ToolbarView(props: ToolbarViewProps): JSX.Element
|
|||||||
{ (unseenInventoryCount > 0) && (
|
{ (unseenInventoryCount > 0) && (
|
||||||
<div className="position-absolute bg-danger px-1 py-0 rounded shadow count">{ unseenInventoryCount }</div>) }
|
<div className="position-absolute bg-danger px-1 py-0 rounded shadow count">{ unseenInventoryCount }</div>) }
|
||||||
</li>
|
</li>
|
||||||
<li className="list-group-item">
|
<li className="list-group-item" onClick={ event => handleToolbarItemClick(event, ToolbarViewItems.FRIEND_LIST_ITEM) }>
|
||||||
<i className="icon icon-friendall"></i>
|
<i className="icon icon-friendall"></i>
|
||||||
{ (unseenFriendListCount > 0) && (
|
{ (unseenFriendListCount > 0) && (
|
||||||
<div className="position-absolute bg-danger px-1 py-0 rounded shadow count">{ unseenFriendListCount }</div>) }
|
<div className="position-absolute bg-danger px-1 py-0 rounded shadow count">{ unseenFriendListCount }</div>) }
|
||||||
|
@ -5,7 +5,8 @@ export interface ToolbarViewProps
|
|||||||
|
|
||||||
export class ToolbarViewItems
|
export class ToolbarViewItems
|
||||||
{
|
{
|
||||||
public static NAVIGATOR_ITEM: string = 'TVI_NAVIGATOR_ITEM';
|
public static NAVIGATOR_ITEM: string = 'TVI_NAVIGATOR_ITEM';
|
||||||
public static INVENTORY_ITEM: string = 'TVI_INVENTORY_ITEM';
|
public static INVENTORY_ITEM: string = 'TVI_INVENTORY_ITEM';
|
||||||
public static CATALOG_ITEM: string = 'TVI_CATALOG_ITEM';
|
public static CATALOG_ITEM: string = 'TVI_CATALOG_ITEM';
|
||||||
|
public static FRIEND_LIST_ITEM: string = 'TVI_FRIEND_LIST_ITEM';
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user