This commit is contained in:
MyNameIsBatman 2021-08-30 19:53:13 -03:00
parent ee1fcad71c
commit 06b8492b84
19 changed files with 298 additions and 57 deletions

View File

@ -0,0 +1,7 @@
import { GroupInformationComposer } from '@nitrots/nitro-renderer';
import { SendMessageHook } from '../../hooks';
export function GetGroupInformation(groupId: number): void
{
SendMessageHook(new GroupInformationComposer(groupId, true));
}

1
src/api/groups/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './GetGroupInformation';

View File

@ -1,4 +1,5 @@
export * from './core'; export * from './core';
export * from './groups';
export * from './navigator'; export * from './navigator';
export * from './nitro'; export * from './nitro';
export * from './utils'; export * from './utils';

View File

@ -3,6 +3,11 @@
src: url('../webfonts/Ubuntu.ttf'); src: url('../webfonts/Ubuntu.ttf');
} }
@font-face {
font-family: GameUbuntu;
src: url('../webfonts/Ubuntu-C.ttf');
}
@font-face { @font-face {
font-family: UbuntuItalics; font-family: UbuntuItalics;
src: url('../webfonts/Ubuntu-i.ttf'); src: url('../webfonts/Ubuntu-i.ttf');

Binary file not shown.

View File

@ -3,7 +3,7 @@
html, html,
body { body {
font-family: 'Ubuntu Condensed', sans-serif; font-family: GameUbuntu, sans-serif;
margin: 0; margin: 0;
padding: 0; padding: 0;
width: 100%; width: 100%;
@ -12,8 +12,6 @@ body {
user-select: none; user-select: none;
image-rendering: pixelated; image-rendering: pixelated;
image-rendering: -moz-crisp-edges; image-rendering: -moz-crisp-edges;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
} }
@import './App'; @import './App';

View File

@ -1 +1,3 @@
@import './views/information/GroupInformationView'; @import './views/information/GroupInformationView';
@import './views/information-standalone/GroupInformationStandaloneView';
@import './views/room-information/GroupRoomInformationView';

View File

@ -1,6 +1,11 @@
import { FC } from 'react'; import { FC } from 'react';
import { GroupInformationBoxView } from './views/information-standalone/GroupInformationStandaloneView';
export const GroupsView: FC<{}> = props => export const GroupsView: FC<{}> = props =>
{ {
return null; return (
<>
<GroupInformationBoxView />
</>
);
}; };

View File

@ -0,0 +1,3 @@
.nitro-group-information-standalone {
width: 500px;
}

View File

@ -0,0 +1,35 @@
import { GroupInformationEvent, GroupInformationParser } from '@nitrots/nitro-renderer';
import { FC, useCallback, useState } from 'react';
import { LocalizeText } from '../../../../api';
import { CreateMessageHook } from '../../../../hooks';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
import { GroupInformationView } from '../information/GroupInformationView';
export const GroupInformationBoxView: FC<{}> = props =>
{
const [ groupInformation, setGroupInformation ] = useState<GroupInformationParser>(null);
const onGroupInformationEvent = useCallback((event: GroupInformationEvent) =>
{
const parser = event.getParser();
if(!parser.flag) return;
if(groupInformation) setGroupInformation(null);
setGroupInformation(parser);
}, [ groupInformation ]);
CreateMessageHook(GroupInformationEvent, onGroupInformationEvent);
if(!groupInformation) return null;
return (
<NitroCardView className="nitro-group-information-standalone" simple={ true }>
<NitroCardHeaderView headerText={ LocalizeText('group.window.title') } onCloseClick={ () => setGroupInformation(null) } />
<NitroCardContentView className="pb-2">
<GroupInformationView groupInformation={ groupInformation } onClose={ () => setGroupInformation(null) } />
</NitroCardContentView>
</NitroCardView>
);
};

View File

@ -1,7 +1,8 @@
import { GroupInformationComposer, GroupInformationEvent, GroupInformationParser, GroupJoinComposer, GroupRemoveMemberComposer } from '@nitrots/nitro-renderer'; import { GroupDeleteComposer, GroupInformationComposer, GroupJoinComposer, GroupRemoveMemberComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react'; import { FC, useCallback } from 'react';
import { GetSessionDataManager, LocalizeText } from '../../../../api'; import { CreateLinkEvent, GetSessionDataManager, LocalizeText, TryVisitRoom } from '../../../../api';
import { CreateMessageHook, SendMessageHook } from '../../../../hooks'; import { SendMessageHook } from '../../../../hooks';
import { CatalogPageName } from '../../../catalog/common/CatalogPageName';
import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView'; import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView';
import { GroupMembershipType } from '../../common/GroupMembershipType'; import { GroupMembershipType } from '../../common/GroupMembershipType';
import { GroupType } from '../../common/GroupType'; import { GroupType } from '../../common/GroupType';
@ -9,26 +10,7 @@ import { GroupInformationViewProps } from './GroupInformationView.types';
export const GroupInformationView: FC<GroupInformationViewProps> = props => export const GroupInformationView: FC<GroupInformationViewProps> = props =>
{ {
const { group = null, onLeaveGroup = null } = props; const { groupInformation = null, onClose = null } = props;
const [ groupInformation, setGroupInformation ] = useState<GroupInformationParser>(null);
useEffect(() =>
{
setGroupInformation(null);
if(group) SendMessageHook(new GroupInformationComposer(group.id, false));
}, [ group ]);
const onGroupInformationEvent = useCallback((event: GroupInformationEvent) =>
{
const parser = event.getParser();
if(groupInformation) setGroupInformation(null);
setGroupInformation(parser);
}, [ groupInformation ]);
CreateMessageHook(GroupInformationEvent, onGroupInformationEvent);
const tryJoinGroup = useCallback(() => const tryJoinGroup = useCallback(() =>
{ {
@ -42,32 +24,32 @@ export const GroupInformationView: FC<GroupInformationViewProps> = props =>
{ {
SendMessageHook(new GroupRemoveMemberComposer(groupInformation.id, GetSessionDataManager().userId)); SendMessageHook(new GroupRemoveMemberComposer(groupInformation.id, GetSessionDataManager().userId));
SendMessageHook(new GroupInformationComposer(groupInformation.id, false)); SendMessageHook(new GroupInformationComposer(groupInformation.id, false));
if(onLeaveGroup) onLeaveGroup(); if(onClose) onClose();
}, [ groupInformation, onLeaveGroup ]); }, [ groupInformation, onClose ]);
const isOwner = useCallback(() => const isRealOwner = useCallback(() =>
{ {
if(!group) return false; if(!groupInformation) return false;
return (group.ownerId === GetSessionDataManager().userId); return (groupInformation.ownerName === GetSessionDataManager().userName);
}, [ group, groupInformation ]); }, [ groupInformation ]);
const getRoleIcon = useCallback(() => const getRoleIcon = useCallback(() =>
{ {
if(groupInformation.membershipType === GroupMembershipType.NOT_MEMBER || groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return null; if(groupInformation.membershipType === GroupMembershipType.NOT_MEMBER || groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return null;
if(isOwner()) return <i className="icon icon-group-owner" title={ LocalizeText('group.youareowner') } />; if(isRealOwner()) return <i className="icon icon-group-owner" title={ LocalizeText('group.youareowner') } />;
if(groupInformation.isAdmin) return <i className="icon icon-group-admin" title={ LocalizeText('group.youareadmin') } />; if(groupInformation.isAdmin) return <i className="icon icon-group-admin" title={ LocalizeText('group.youareadmin') } />;
return <i className="icon icon-group-member" title={ LocalizeText('group.youaremember') } />; return <i className="icon icon-group-member" title={ LocalizeText('group.youaremember') } />;
}, [ groupInformation, isOwner ]); }, [ groupInformation, isRealOwner ]);
const getButtonText = useCallback(() => const getButtonText = useCallback(() =>
{ {
if(groupInformation.type === GroupType.PRIVATE) return ''; if(groupInformation.type === GroupType.PRIVATE) return '';
if(isOwner()) return 'group.youareowner'; if(isRealOwner()) return 'group.youareowner';
if(groupInformation.membershipType === GroupMembershipType.MEMBER) return 'group.leave'; if(groupInformation.membershipType === GroupMembershipType.MEMBER) return 'group.leave';
@ -79,7 +61,7 @@ export const GroupInformationView: FC<GroupInformationViewProps> = props =>
if(groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return 'group.membershippending'; if(groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return 'group.membershippending';
} }
}, [ groupInformation, isOwner ]); }, [ groupInformation, isRealOwner ]);
const handleButtonClick = useCallback(() => const handleButtonClick = useCallback(() =>
{ {
@ -90,13 +72,33 @@ export const GroupInformationView: FC<GroupInformationViewProps> = props =>
return tryJoinGroup(); return tryJoinGroup();
}, [ groupInformation, tryLeaveGroup, tryJoinGroup ]); }, [ groupInformation, tryLeaveGroup, tryJoinGroup ]);
if(!group || !groupInformation) return null; const handleAction = useCallback((action: string) =>
{
switch(action)
{
case 'homeroom':
TryVisitRoom(groupInformation.roomId);
break;
case 'furniture':
CreateLinkEvent('catalog/open/' + CatalogPageName.GUILD_CUSTOM_FURNI);
break;
case 'delete':
if(window.confirm(LocalizeText('group.deleteconfirm.title') + ' - ' + LocalizeText('group.deleteconfirm.desc')))
{
SendMessageHook(new GroupDeleteComposer(groupInformation.id));
if(onClose) onClose();
}
break;
}
}, [ groupInformation, onClose ]);
if(!groupInformation) return null;
return ( return (
<div className="group-information p-2"> <div className="group-information text-black p-2">
<div> <div>
<div className="group-badge text-center"> <div className="group-badge text-center">
<BadgeImageView badgeCode={ group.badge } isGroup={ true } /> <BadgeImageView badgeCode={ groupInformation.badge } isGroup={ true } />
<div className="mt-3"> <div className="mt-3">
<a href="#" className="small text-black"> <a href="#" className="small text-black">
{ LocalizeText('group.membercount', ['totalMembers'], [groupInformation.membersCount.toString()]) } { LocalizeText('group.membercount', ['totalMembers'], [groupInformation.membersCount.toString()]) }
@ -110,23 +112,28 @@ export const GroupInformationView: FC<GroupInformationViewProps> = props =>
<div className="mt-3"> <div className="mt-3">
{ getRoleIcon() } { getRoleIcon() }
</div> </div>
<div>
{ groupInformation.isOwner && <a href="#" className="small text-danger" onClick={ () => handleAction('delete') }>
{ LocalizeText('group.delete') }
</a> }
</div>
</div> </div>
</div> </div>
<div className="ms-2 w-100"> <div className="ms-2 w-100">
<div className="fw-bold d-flex align-items-center"> <div className="fw-bold d-flex align-items-center">
<i className={ 'icon icon-group-type-' + groupInformation.type } /> <i className={ 'icon icon-group-type-' + groupInformation.type } />
{ groupInformation.canMembersDecorate && <i className="icon icon-group-decorate ms-1" /> } { groupInformation.canMembersDecorate && <i className="icon icon-group-decorate ms-1" /> }
<div className="ms-1">{ group.title }</div> <div className="ms-1">{ groupInformation.title }</div>
</div> </div>
<div>{ LocalizeText('group.created', ['date', 'owner'], [groupInformation.createdAt, groupInformation.ownerName]) }</div> <div>{ LocalizeText('group.created', ['date', 'owner'], [groupInformation.createdAt, groupInformation.ownerName]) }</div>
<div className="group-description small overflow-auto">{ groupInformation.description }</div> <div className="group-description small overflow-auto">{ groupInformation.description }</div>
<div> <div>
<a href="#" className="small text-black"> <a href="#" className="small text-black" onClick={ () => handleAction('homeroom') }>
{ LocalizeText('group.linktobase') } { LocalizeText('group.linktobase') }
</a> </a>
</div> </div>
<div> <div>
<a href="#" className="small text-black"> <a href="#" className="small text-black" onClick={ () => handleAction('furniture') }>
{ LocalizeText('group.buyfurni') } { LocalizeText('group.buyfurni') }
</a> </a>
</div> </div>
@ -136,7 +143,7 @@ export const GroupInformationView: FC<GroupInformationViewProps> = props =>
</a> </a>
</div> </div>
{ groupInformation.type !== GroupType.PRIVATE && { groupInformation.type !== GroupType.PRIVATE &&
<button className="btn btn-primary w-100 mt-2" disabled={ groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING || isOwner() } onClick={ handleButtonClick }> <button className="btn btn-primary w-100 mt-2" disabled={ groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING || isRealOwner() } onClick={ handleButtonClick }>
{ LocalizeText(getButtonText()) } { LocalizeText(getButtonText()) }
</button> </button>
} }

View File

@ -1,7 +1,7 @@
import { GroupDataParser } from '@nitrots/nitro-renderer'; import { GroupInformationParser } from '@nitrots/nitro-renderer';
export interface GroupInformationViewProps export interface GroupInformationViewProps
{ {
group: GroupDataParser; groupInformation: GroupInformationParser;
onLeaveGroup?: () => void; onClose?: () => void;
} }

View File

@ -0,0 +1,13 @@
.nitro-group-room-information {
pointer-events: all;
padding: 2px;
background-color: $gable-green;
border: 2px solid rgba($white, 0.5);
font-size: $font-size-sm;
margin-bottom: 5px;
.group-badge {
width: 50px;
height: 50px;
}
}

View File

@ -0,0 +1,123 @@
import { DesktopViewEvent, GroupInformationComposer, GroupInformationEvent, GroupInformationParser, GroupJoinComposer, GroupRemoveMemberComposer, RoomInfoEvent } from '@nitrots/nitro-renderer';
import { FC, useCallback, useState } from 'react';
import { GetGroupInformation, GetSessionDataManager, LocalizeText } from '../../../../api';
import { CreateMessageHook, SendMessageHook } from '../../../../hooks';
import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView';
import { GroupMembershipType } from '../../common/GroupMembershipType';
import { GroupType } from '../../common/GroupType';
export const GroupRoomInformationView: FC<{}> = props =>
{
const [ groupId, setGroupId ] = useState<number>(null);
const [ groupInformation, setGroupInformation ] = useState<GroupInformationParser>(null);
const [ isExpended, setIsExpended ] = useState<boolean>(true);
const onRoomInfoEvent = useCallback((event: RoomInfoEvent) =>
{
const parser = event.getParser();
setGroupInformation(null);
if(parser.data.habboGroupId)
{
setGroupId(parser.data.habboGroupId);
SendMessageHook(new GroupInformationComposer(parser.data.habboGroupId, false));
}
}, []);
CreateMessageHook(RoomInfoEvent, onRoomInfoEvent);
const onGroupInformationEvent = useCallback((event: GroupInformationEvent) =>
{
const parser = event.getParser();
if(parser.flag || groupId !== parser.id) return;
setGroupInformation(null);
setGroupInformation(parser);
}, [ groupId ]);
CreateMessageHook(GroupInformationEvent, onGroupInformationEvent);
const onDesktopViewEvent = useCallback((event: DesktopViewEvent) =>
{
setGroupId(0);
setGroupInformation(null);
}, []);
CreateMessageHook(DesktopViewEvent, onDesktopViewEvent);
const isRealOwner = useCallback(() =>
{
if(!groupInformation) return false;
return (groupInformation.ownerName === GetSessionDataManager().userName);
}, [ groupInformation ]);
const tryJoinGroup = useCallback(() =>
{
if(!groupInformation) return;
SendMessageHook(new GroupJoinComposer(groupInformation.id));
SendMessageHook(new GroupInformationComposer(groupInformation.id, false));
}, [ groupInformation ]);
const tryLeaveGroup = useCallback(() =>
{
SendMessageHook(new GroupRemoveMemberComposer(groupInformation.id, GetSessionDataManager().userId));
SendMessageHook(new GroupInformationComposer(groupInformation.id, false));
}, [ groupInformation ]);
const getButtonText = useCallback(() =>
{
if(groupInformation.type === GroupType.PRIVATE) return '';
if(isRealOwner()) return 'group.youareowner';
if(groupInformation.membershipType === GroupMembershipType.MEMBER) return 'group.leave';
if(groupInformation.membershipType === GroupMembershipType.NOT_MEMBER && groupInformation.type === GroupType.REGULAR) return 'group.join';
if(groupInformation.type === GroupType.EXCLUSIVE)
{
if(groupInformation.membershipType === GroupMembershipType.NOT_MEMBER) return 'group.requestmembership';
if(groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return 'group.membershippending';
}
}, [ groupInformation, isRealOwner ]);
const handleButtonClick = useCallback(() =>
{
if(groupInformation.type === GroupType.PRIVATE && groupInformation.membershipType === GroupMembershipType.NOT_MEMBER) return;
if(groupInformation.membershipType === GroupMembershipType.MEMBER) return tryLeaveGroup();
return tryJoinGroup();
}, [ groupInformation, tryLeaveGroup, tryJoinGroup ]);
if(!groupInformation) return null;
return (
<div className="nitro-group-room-information rounded py-1 px-2">
<div className="d-flex justify-content-between align-items-center cursor-pointer" onClick={ () => setIsExpended(value => !value) }>
<div>{ LocalizeText('group.homeroominfo.title') }</div>
<i className={ 'fas fa-chevron-' + (isExpended ? 'up' : 'down') } />
</div>
{ isExpended && <>
<div className="d-flex cursor-pointer" onClick={ () => GetGroupInformation(groupInformation.id) }>
<div className="group-badge flex-shrink-0 me-1">
<BadgeImageView badgeCode={ groupInformation.badge } isGroup={ true } />
</div>
<div>
{ groupInformation.title }
</div>
</div>
{ groupInformation.type !== GroupType.PRIVATE && !isRealOwner() &&
<button className="btn btn-sm btn-primary w-100 mt-1" disabled={ groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING || isRealOwner() } onClick={ handleButtonClick }>
{ LocalizeText(getButtonText()) }
</button>
}
</> }
</div>
);
};

View File

@ -6,6 +6,7 @@ import { AchievementsView } from '../achievements/AchievementsView';
import { AvatarEditorView } from '../avatar-editor/AvatarEditorView'; import { AvatarEditorView } from '../avatar-editor/AvatarEditorView';
import { CatalogView } from '../catalog/CatalogView'; import { CatalogView } from '../catalog/CatalogView';
import { FriendListView } from '../friend-list/FriendListView'; import { FriendListView } from '../friend-list/FriendListView';
import { GroupsView } from '../groups/GroupsView';
import { HotelView } from '../hotel-view/HotelView'; import { HotelView } from '../hotel-view/HotelView';
import { InventoryView } from '../inventory/InventoryView'; import { InventoryView } from '../inventory/InventoryView';
import { ModToolsView } from '../mod-tools/ModToolsView'; import { ModToolsView } from '../mod-tools/ModToolsView';
@ -62,6 +63,7 @@ export const MainView: FC<MainViewProps> = props =>
<RightSideView /> <RightSideView />
<UserSettingsView /> <UserSettingsView />
<UserProfileView /> <UserProfileView />
<GroupsView />
</div> </div>
); );
} }

View File

@ -1,4 +1,5 @@
import { FC } from 'react'; import { FC } from 'react';
import { GroupRoomInformationView } from '../groups/views/room-information/GroupRoomInformationView';
import { NotificationCenterView } from '../notification-center/NotificationCenterView'; import { NotificationCenterView } from '../notification-center/NotificationCenterView';
import { PurseView } from '../purse/PurseView'; import { PurseView } from '../purse/PurseView';
import { RightSideProps } from './RightSideView.types'; import { RightSideProps } from './RightSideView.types';
@ -9,6 +10,7 @@ export const RightSideView: FC<RightSideProps> = props =>
<div className="nitro-right-side"> <div className="nitro-right-side">
<div className="position-relative d-flex flex-column"> <div className="position-relative d-flex flex-column">
<PurseView /> <PurseView />
<GroupRoomInformationView />
<NotificationCenterView /> <NotificationCenterView />
</div> </div>
</div> </div>

View File

@ -62,7 +62,7 @@
word-break: break-word; word-break: break-word;
max-width: 350px; max-width: 350px;
min-height: 25px; min-height: 25px;
font-size: $font-size-sm; font-size: 15px;
border-image-slice: 17 6 6 29 fill; border-image-slice: 17 6 6 29 fill;
border-image-width: 17px 6px 6px 29px; border-image-width: 17px 6px 6px 29px;

View File

@ -1,5 +1,7 @@
import { GroupInformationComposer, GroupInformationEvent, GroupInformationParser } from '@nitrots/nitro-renderer';
import classNames from 'classnames'; import classNames from 'classnames';
import { FC, useEffect, useState } from 'react'; import { FC, useCallback, useEffect, useState } from 'react';
import { CreateMessageHook, SendMessageHook } from '../../../../hooks';
import { GroupInformationView } from '../../../groups/views/information/GroupInformationView'; import { GroupInformationView } from '../../../groups/views/information/GroupInformationView';
import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView'; import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView';
import { GroupsContainerViewProps } from './GroupsContainerView.types'; import { GroupsContainerViewProps } from './GroupsContainerView.types';
@ -8,12 +10,31 @@ export const GroupsContainerView: FC<GroupsContainerViewProps> = props =>
{ {
const { groups = null, onLeaveGroup = null } = props; const { groups = null, onLeaveGroup = null } = props;
const [ selectedIndex, setSelectedIndex ] = useState<number>(null); const [ selectedGroupId, setSelectedGroupId ] = useState<number>(null);
const [ groupInformation, setGroupInformation ] = useState<GroupInformationParser>(null);
const onGroupInformationEvent = useCallback((event: GroupInformationEvent) =>
{
const parser = event.getParser();
if(!selectedGroupId || selectedGroupId !== parser.id || parser.flag) return;
if(groupInformation) setGroupInformation(null);
setGroupInformation(parser);
}, [ groupInformation, selectedGroupId ]);
CreateMessageHook(GroupInformationEvent, onGroupInformationEvent);
useEffect(() => useEffect(() =>
{ {
if(groups.length > 0 && selectedIndex === null) setSelectedIndex(0); if(groups.length > 0 && !selectedGroupId) setSelectedGroupId(groups[0].id);
}, [ groups ]); }, [ groups, selectedGroupId ]);
useEffect(() =>
{
if(selectedGroupId) SendMessageHook(new GroupInformationComposer(selectedGroupId, false));
}, [ selectedGroupId ]);
if(!groups) return null; if(!groups) return null;
@ -23,14 +44,14 @@ export const GroupsContainerView: FC<GroupsContainerViewProps> = props =>
<div className="h-100 overflow-auto d-flex flex-column gap-1"> <div className="h-100 overflow-auto d-flex flex-column gap-1">
{ groups.map((group, index) => { groups.map((group, index) =>
{ {
return <div key={ index } onClick={ () => setSelectedIndex(index) } className={ 'profile-groups-item flex-shrink-0 d-flex align-items-center justify-content-center cursor-pointer' + classNames({ ' active': selectedIndex === index }) }> return <div key={ index } onClick={ () => setSelectedGroupId(group.id) } className={ 'profile-groups-item flex-shrink-0 d-flex align-items-center justify-content-center cursor-pointer' + classNames({ ' active': selectedGroupId === group.id }) }>
<BadgeImageView badgeCode={ group.badge } isGroup={ true } /> <BadgeImageView badgeCode={ group.badge } isGroup={ true } />
</div> </div>
}) } }) }
</div> </div>
</div> </div>
<div className="w-100"> <div className="w-100">
{ selectedIndex > -1 && <GroupInformationView group={ groups[selectedIndex] } onLeaveGroup={ onLeaveGroup } /> } { groupInformation && <GroupInformationView groupInformation={ groupInformation } onClose={ onLeaveGroup } /> }
</div> </div>
</div> </div>
); );

View File

@ -3,36 +3,52 @@
padding:7px; padding:7px;
.icon { .icon {
width: 16px;
height: 9px;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
&.icon-mv-1 { &.icon-mv-1 {
width: 16px;
height: 9px;
background-image: url('../../assets/images/wired/icon_wired_around.png'); background-image: url('../../assets/images/wired/icon_wired_around.png');
} }
&.icon-mv-2 { &.icon-mv-2 {
width: 16px;
height: 9px;
background-image: url('../../assets/images/wired/icon_wired_up_down.png'); background-image: url('../../assets/images/wired/icon_wired_up_down.png');
} }
&.icon-mv-3 { &.icon-mv-3 {
width: 16px;
height: 9px;
background-image: url('../../assets/images/wired/icon_wired_left_right.png'); background-image: url('../../assets/images/wired/icon_wired_left_right.png');
} }
&.icon-ne { &.icon-ne {
width: 16px;
height: 9px;
background-image: url('../../assets/images/wired/icon_wired_north_east.png'); background-image: url('../../assets/images/wired/icon_wired_north_east.png');
} }
&.icon-se { &.icon-se {
width: 16px;
height: 9px;
background-image: url('../../assets/images/wired/icon_wired_south_east.png'); background-image: url('../../assets/images/wired/icon_wired_south_east.png');
} }
&.icon-sw { &.icon-sw {
width: 16px;
height: 9px;
background-image: url('../../assets/images/wired/icon_wired_south_west.png'); background-image: url('../../assets/images/wired/icon_wired_south_west.png');
} }
&.icon-nw { &.icon-nw {
width: 16px;
height: 9px;
background-image: url('../../assets/images/wired/icon_wired_north_west.png'); background-image: url('../../assets/images/wired/icon_wired_north_west.png');
} }
&.icon-rot-1 { &.icon-rot-1 {
width: 16px;
height: 9px;
background-image: url('../../assets/images/wired/icon_wired_rotate_clockwise.png'); background-image: url('../../assets/images/wired/icon_wired_rotate_clockwise.png');
} }
&.icon-rot-2 { &.icon-rot-2 {
width: 16px;
height: 9px;
background-image: url('../../assets/images/wired/icon_wired_rotate_counter_clockwise.png'); background-image: url('../../assets/images/wired/icon_wired_rotate_counter_clockwise.png');
} }
} }