diff --git a/src/api/groups/GetGroupInformation.ts b/src/api/groups/GetGroupInformation.ts new file mode 100644 index 00000000..7f37e004 --- /dev/null +++ b/src/api/groups/GetGroupInformation.ts @@ -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)); +} diff --git a/src/api/groups/index.ts b/src/api/groups/index.ts new file mode 100644 index 00000000..cc1c46d3 --- /dev/null +++ b/src/api/groups/index.ts @@ -0,0 +1 @@ +export * from './GetGroupInformation'; diff --git a/src/api/index.ts b/src/api/index.ts index c44fa18e..77777005 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,4 +1,5 @@ export * from './core'; +export * from './groups'; export * from './navigator'; export * from './nitro'; export * from './utils'; diff --git a/src/assets/styles/fonts.scss b/src/assets/styles/fonts.scss index ea9baf34..2dabd11f 100644 --- a/src/assets/styles/fonts.scss +++ b/src/assets/styles/fonts.scss @@ -3,6 +3,11 @@ src: url('../webfonts/Ubuntu.ttf'); } +@font-face { + font-family: GameUbuntu; + src: url('../webfonts/Ubuntu-C.ttf'); +} + @font-face { font-family: UbuntuItalics; src: url('../webfonts/Ubuntu-i.ttf'); diff --git a/src/assets/styles/icons.scss b/src/assets/styles/icons.scss index b80928fd..46ae31e4 100644 --- a/src/assets/styles/icons.scss +++ b/src/assets/styles/icons.scss @@ -521,7 +521,7 @@ &.icon-pf-offline { background: url('../images/profile/icons/offline.png'); - width: 40px; + width: 39px; height: 16px; } diff --git a/src/assets/webfonts/Ubuntu-C.ttf b/src/assets/webfonts/Ubuntu-C.ttf new file mode 100644 index 00000000..8e2c4bc2 Binary files /dev/null and b/src/assets/webfonts/Ubuntu-C.ttf differ diff --git a/src/index.scss b/src/index.scss index 73ca3e87..cbfa7106 100644 --- a/src/index.scss +++ b/src/index.scss @@ -3,7 +3,7 @@ html, body { - font-family: 'Ubuntu Condensed', sans-serif; + font-family: GameUbuntu, sans-serif; margin: 0; padding: 0; width: 100%; @@ -12,8 +12,6 @@ body { user-select: none; image-rendering: pixelated; image-rendering: -moz-crisp-edges; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; } @import './App'; diff --git a/src/views/groups/GroupView.scss b/src/views/groups/GroupView.scss index 32ca5256..44eafba0 100644 --- a/src/views/groups/GroupView.scss +++ b/src/views/groups/GroupView.scss @@ -1 +1,3 @@ -@import './views/GroupinformationView'; +@import './views/information/GroupInformationView'; +@import './views/information-standalone/GroupInformationStandaloneView'; +@import './views/room-information/GroupRoomInformationView'; diff --git a/src/views/groups/GroupsView.tsx b/src/views/groups/GroupsView.tsx index 5e42c775..c4e95a69 100644 --- a/src/views/groups/GroupsView.tsx +++ b/src/views/groups/GroupsView.tsx @@ -1,6 +1,11 @@ import { FC } from 'react'; +import { GroupInformationBoxView } from './views/information-standalone/GroupInformationStandaloneView'; export const GroupsView: FC<{}> = props => { - return null; + return ( + <> + + + ); }; diff --git a/src/views/groups/views/GroupInformationView.tsx b/src/views/groups/views/GroupInformationView.tsx deleted file mode 100644 index 57db4ca2..00000000 --- a/src/views/groups/views/GroupInformationView.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { GroupInformationComposer, GroupInformationEvent, GroupInformationParser } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useState } from 'react'; -import { 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'; -import { GroupInformationViewProps } from './GroupInformationView.types'; - -export const GroupInformationView: FC = props => -{ - const { group = null } = props; - - const [ groupInformation, setGroupInformation ] = useState(null); - - useEffect(() => - { - setGroupInformation(null); - if(group) SendMessageHook(new GroupInformationComposer(group.id, true)); - }, [ group ]); - - const onGroupInformationEvent = useCallback((event: GroupInformationEvent) => - { - const parser = event.getParser(); - setGroupInformation(parser); - }, []); - - CreateMessageHook(GroupInformationEvent, onGroupInformationEvent); - - if(!groupInformation) return null; - - return ( -
-
-
- - - -
- { groupInformation.membershipType === GroupMembershipType.MEMBER && !groupInformation.isAdmin && } - { groupInformation.isAdmin && !groupInformation.isOwner && } - { groupInformation.isOwner && } -
-
-
-
-
- - { groupInformation.canMembersDecorate && } -
{ group.title }
-
-
{ LocalizeText('group.created', ['date', 'owner'], [groupInformation.createdAt, groupInformation.ownerName]) }
-
{ groupInformation.description }
- - - - { groupInformation.type !== GroupType.PRIVATE && - - } -
-
- ); -}; diff --git a/src/views/groups/views/GroupInformationView.types.ts b/src/views/groups/views/GroupInformationView.types.ts deleted file mode 100644 index 70aae855..00000000 --- a/src/views/groups/views/GroupInformationView.types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GroupDataParser } from '@nitrots/nitro-renderer'; - -export interface GroupInformationViewProps -{ - group: GroupDataParser; -} diff --git a/src/views/groups/views/information-standalone/GroupInformationStandaloneView.scss b/src/views/groups/views/information-standalone/GroupInformationStandaloneView.scss new file mode 100644 index 00000000..c431fe7c --- /dev/null +++ b/src/views/groups/views/information-standalone/GroupInformationStandaloneView.scss @@ -0,0 +1,3 @@ +.nitro-group-information-standalone { + width: 500px; +} diff --git a/src/views/groups/views/information-standalone/GroupInformationStandaloneView.tsx b/src/views/groups/views/information-standalone/GroupInformationStandaloneView.tsx new file mode 100644 index 00000000..5d43f920 --- /dev/null +++ b/src/views/groups/views/information-standalone/GroupInformationStandaloneView.tsx @@ -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(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 ( + + setGroupInformation(null) } /> + + setGroupInformation(null) } /> + + + ); +}; diff --git a/src/views/groups/views/GroupinformationView.scss b/src/views/groups/views/information/GroupInformationView.scss similarity index 100% rename from src/views/groups/views/GroupinformationView.scss rename to src/views/groups/views/information/GroupInformationView.scss diff --git a/src/views/groups/views/information/GroupInformationView.tsx b/src/views/groups/views/information/GroupInformationView.tsx new file mode 100644 index 00000000..8d4837d0 --- /dev/null +++ b/src/views/groups/views/information/GroupInformationView.tsx @@ -0,0 +1,153 @@ +import { GroupDeleteComposer, GroupInformationComposer, GroupJoinComposer, GroupRemoveMemberComposer } from '@nitrots/nitro-renderer'; +import { FC, useCallback } from 'react'; +import { CreateLinkEvent, GetSessionDataManager, LocalizeText, TryVisitRoom } from '../../../../api'; +import { SendMessageHook } from '../../../../hooks'; +import { CatalogPageName } from '../../../catalog/common/CatalogPageName'; +import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView'; +import { GroupMembershipType } from '../../common/GroupMembershipType'; +import { GroupType } from '../../common/GroupType'; +import { GroupInformationViewProps } from './GroupInformationView.types'; + +export const GroupInformationView: FC = props => +{ + const { groupInformation = null, onClose = null } = props; + + 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)); + if(onClose) onClose(); + }, [ groupInformation, onClose ]); + + const isRealOwner = useCallback(() => + { + if(!groupInformation) return false; + + return (groupInformation.ownerName === GetSessionDataManager().userName); + }, [ groupInformation ]); + + const getRoleIcon = useCallback(() => + { + if(groupInformation.membershipType === GroupMembershipType.NOT_MEMBER || groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return null; + + if(isRealOwner()) return ; + + if(groupInformation.isAdmin) return ; + + return ; + }, [ groupInformation, isRealOwner ]); + + 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 ]); + + 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 ( +
+ +
+
+ + { groupInformation.canMembersDecorate && } +
{ groupInformation.title }
+
+
{ LocalizeText('group.created', ['date', 'owner'], [groupInformation.createdAt, groupInformation.ownerName]) }
+
{ groupInformation.description }
+ + + + { groupInformation.type !== GroupType.PRIVATE && + + } +
+
+ ); +}; diff --git a/src/views/groups/views/information/GroupInformationView.types.ts b/src/views/groups/views/information/GroupInformationView.types.ts new file mode 100644 index 00000000..b8544e6f --- /dev/null +++ b/src/views/groups/views/information/GroupInformationView.types.ts @@ -0,0 +1,7 @@ +import { GroupInformationParser } from '@nitrots/nitro-renderer'; + +export interface GroupInformationViewProps +{ + groupInformation: GroupInformationParser; + onClose?: () => void; +} diff --git a/src/views/groups/views/room-information/GroupRoomInformationView.scss b/src/views/groups/views/room-information/GroupRoomInformationView.scss new file mode 100644 index 00000000..9c1ac19c --- /dev/null +++ b/src/views/groups/views/room-information/GroupRoomInformationView.scss @@ -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; + } +} diff --git a/src/views/groups/views/room-information/GroupRoomInformationView.tsx b/src/views/groups/views/room-information/GroupRoomInformationView.tsx new file mode 100644 index 00000000..1daeb313 --- /dev/null +++ b/src/views/groups/views/room-information/GroupRoomInformationView.tsx @@ -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(null); + const [ groupInformation, setGroupInformation ] = useState(null); + const [ isExpended, setIsExpended ] = useState(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 ( +
+
setIsExpended(value => !value) }> +
{ LocalizeText('group.homeroominfo.title') }
+ +
+ { isExpended && <> +
GetGroupInformation(groupInformation.id) }> +
+ +
+
+ { groupInformation.title } +
+
+ { groupInformation.type !== GroupType.PRIVATE && !isRealOwner() && + + } + } +
+ ); +}; diff --git a/src/views/main/MainView.tsx b/src/views/main/MainView.tsx index 657f778c..88ba1efe 100644 --- a/src/views/main/MainView.tsx +++ b/src/views/main/MainView.tsx @@ -6,6 +6,7 @@ import { AchievementsView } from '../achievements/AchievementsView'; import { AvatarEditorView } from '../avatar-editor/AvatarEditorView'; import { CatalogView } from '../catalog/CatalogView'; import { FriendListView } from '../friend-list/FriendListView'; +import { GroupsView } from '../groups/GroupsView'; import { HotelView } from '../hotel-view/HotelView'; import { InventoryView } from '../inventory/InventoryView'; import { ModToolsView } from '../mod-tools/ModToolsView'; @@ -62,6 +63,7 @@ export const MainView: FC = props => + ); } diff --git a/src/views/navigator/views/room-info/NavigatorRoomInfoView.scss b/src/views/navigator/views/room-info/NavigatorRoomInfoView.scss index 9763a4fc..4e6c4ae9 100644 --- a/src/views/navigator/views/room-info/NavigatorRoomInfoView.scss +++ b/src/views/navigator/views/room-info/NavigatorRoomInfoView.scss @@ -1,5 +1,5 @@ .nitro-room-info { - width: 230px; + width: 250px; .gray { filter: grayscale(1); @@ -17,4 +17,9 @@ background-color: rgba($black, .125); border-color: $black !important; } + + .group-badge { + width: 50px; + height: 50px; + } } diff --git a/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx b/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx index 62e789f7..e57f6b84 100644 --- a/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx +++ b/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx @@ -1,7 +1,7 @@ -import { RoomMuteComposer, RoomSettingsComposer, RoomStaffPickComposer, UserHomeRoomComposer } from '@nitrots/nitro-renderer'; +import { RoomMuteComposer, RoomSettingsComposer, RoomStaffPickComposer, SecurityLevel, UserHomeRoomComposer } from '@nitrots/nitro-renderer'; import classNames from 'classnames'; import { FC, useCallback, useEffect, useState } from 'react'; -import { GetConfiguration, LocalizeText } from '../../../../api'; +import { GetConfiguration, GetSessionDataManager, LocalizeText } from '../../../../api'; import { NavigatorEvent } from '../../../../events'; import { RoomWidgetThumbnailEvent } from '../../../../events/room-widgets/thumbnail'; import { dispatchUiEvent } from '../../../../hooks/events'; @@ -42,6 +42,16 @@ export const NavigatorRoomInfoView: FC = props => setIsRoomPicked(roomInfoData.enteredGuestRoom.roomPicker); setIsRoomMuted(roomInfoData.enteredGuestRoom.allInRoomMuted); }, [ roomInfoData ]); + + const hasPermission = useCallback((permission: string) => + { + switch(permission) + { + case 'settings': return GetSessionDataManager().securityLevel >= SecurityLevel.MODERATOR || roomInfoData.currentRoomOwner; + case 'staff_pick': return GetSessionDataManager().securityLevel >= SecurityLevel.COMMUNITY; + default: return false; + } + }, [ roomInfoData ]); const processAction = useCallback((action: string, value?: string) => { @@ -131,10 +141,10 @@ export const NavigatorRoomInfoView: FC = props => { roomThumbnail && } { roomInfoData.enteredGuestRoom.habboGroupId > 0 &&
processAction('open_group_info') }> -
+
-
+
{ LocalizeText('navigator.guildbase', ['groupName'], [roomInfoData.enteredGuestRoom.groupName]) }
} @@ -142,11 +152,13 @@ export const NavigatorRoomInfoView: FC = props => { LocalizeText('navigator.embed.caption') }
- - - + { hasPermission('settings') && <> + + + } + { hasPermission('staff_pick') && } - + { hasPermission('settings') && } } diff --git a/src/views/right-side/RightSideView.tsx b/src/views/right-side/RightSideView.tsx index 5917174e..c503a533 100644 --- a/src/views/right-side/RightSideView.tsx +++ b/src/views/right-side/RightSideView.tsx @@ -1,4 +1,5 @@ import { FC } from 'react'; +import { GroupRoomInformationView } from '../groups/views/room-information/GroupRoomInformationView'; import { NotificationCenterView } from '../notification-center/NotificationCenterView'; import { PurseView } from '../purse/PurseView'; import { RightSideProps } from './RightSideView.types'; @@ -9,6 +10,7 @@ export const RightSideView: FC = props =>
+
diff --git a/src/views/room/widgets/chat/message/ChatWidgetMessageView.scss b/src/views/room/widgets/chat/message/ChatWidgetMessageView.scss index e2bbbbbf..9bdbcb6b 100644 --- a/src/views/room/widgets/chat/message/ChatWidgetMessageView.scss +++ b/src/views/room/widgets/chat/message/ChatWidgetMessageView.scss @@ -62,7 +62,7 @@ word-break: break-word; max-width: 350px; min-height: 25px; - font-size: $font-size-sm; + font-size: 15px; border-image-slice: 17 6 6 29 fill; border-image-width: 17px 6px 6px 29px; diff --git a/src/views/user-profile/UserProfileView.tsx b/src/views/user-profile/UserProfileView.tsx index 796fda0d..e732b384 100644 --- a/src/views/user-profile/UserProfileView.tsx +++ b/src/views/user-profile/UserProfileView.tsx @@ -1,6 +1,6 @@ -import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, UserCurrentBadgesComposer, UserCurrentBadgesEvent, UserProfileEvent, UserProfileParser, UserRelationshipsComposer } from '@nitrots/nitro-renderer'; +import { RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, UserCurrentBadgesComposer, UserCurrentBadgesEvent, UserProfileComposer, UserProfileEvent, UserProfileParser, UserRelationshipsComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useState } from 'react'; -import { LocalizeText } from '../../api'; +import { GetSessionDataManager, LocalizeText } from '../../api'; import { CreateMessageHook, SendMessageHook } from '../../hooks'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../layout'; import { BadgesContainerView } from './views/badges-container/BadgesContainerView'; @@ -20,6 +20,11 @@ export const UserProfileView: FC = props => setUserBadges([]); setUserRelationships(null); }, []); + + const onLeaveGroup = useCallback(() => + { + if(userProfile && userProfile.id === GetSessionDataManager().userId) SendMessageHook(new UserProfileComposer(userProfile.id)); + }, [ userProfile ]); const OnUserCurrentBadgesEvent = useCallback((event: UserCurrentBadgesEvent) => { @@ -45,14 +50,14 @@ export const UserProfileView: FC = props => { const parser = event.getParser(); - if(userProfile && userProfile.id !== parser.id) + if(userProfile) { + setUserProfile(null); setUserBadges([]); setUserRelationships(null); } setUserProfile(parser); - console.log(parser); SendMessageHook(new UserCurrentBadgesComposer(parser.id)); SendMessageHook(new UserRelationshipsComposer(parser.id)); }, [userProfile]); @@ -67,8 +72,8 @@ export const UserProfileView: FC = props =>
- - + +
{ @@ -81,7 +86,7 @@ export const UserProfileView: FC = props => {LocalizeText('extendedprofile.rooms')}
- +
) diff --git a/src/views/user-profile/views/badges-container/BadgesContainerView.tsx b/src/views/user-profile/views/badges-container/BadgesContainerView.tsx index ca698bdb..cba4e091 100644 --- a/src/views/user-profile/views/badges-container/BadgesContainerView.tsx +++ b/src/views/user-profile/views/badges-container/BadgesContainerView.tsx @@ -7,7 +7,7 @@ export const BadgesContainerView: FC = props => const { badges = null } = props; return ( -
+
{ diff --git a/src/views/user-profile/views/groups-container/GroupsContainerView.tsx b/src/views/user-profile/views/groups-container/GroupsContainerView.tsx index 8ea5895c..dc7ee616 100644 --- a/src/views/user-profile/views/groups-container/GroupsContainerView.tsx +++ b/src/views/user-profile/views/groups-container/GroupsContainerView.tsx @@ -1,19 +1,40 @@ +import { GroupInformationComposer, GroupInformationEvent, GroupInformationParser } from '@nitrots/nitro-renderer'; import classNames from 'classnames'; -import { FC, useEffect, useState } from 'react'; -import { GroupInformationView } from '../../../groups/views/GroupInformationView'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { CreateMessageHook, SendMessageHook } from '../../../../hooks'; +import { GroupInformationView } from '../../../groups/views/information/GroupInformationView'; import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView'; import { GroupsContainerViewProps } from './GroupsContainerView.types'; export const GroupsContainerView: FC = props => { - const { groups = null } = props; + const { groups = null, onLeaveGroup = null } = props; - const [ selectedIndex, setSelectedIndex ] = useState(null); + const [ selectedGroupId, setSelectedGroupId ] = useState(null); + const [ groupInformation, setGroupInformation ] = useState(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(() => { - if(groups.length > 0 && selectedIndex === null) setSelectedIndex(0); - }, [ groups ]); + if(groups.length > 0 && !selectedGroupId) setSelectedGroupId(groups[0].id); + }, [ groups, selectedGroupId ]); + + useEffect(() => + { + if(selectedGroupId) SendMessageHook(new GroupInformationComposer(selectedGroupId, false)); + }, [ selectedGroupId ]); if(!groups) return null; @@ -23,14 +44,14 @@ export const GroupsContainerView: FC = props =>
{ groups.map((group, index) => { - return
setSelectedIndex(index) } className={ 'profile-groups-item flex-shrink-0 d-flex align-items-center justify-content-center cursor-pointer' + classNames({ ' active': selectedIndex === index }) }> + return
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 }) }>
}) }
- { selectedIndex > -1 && } + { groupInformation && }
); diff --git a/src/views/user-profile/views/groups-container/GroupsContainerView.types.ts b/src/views/user-profile/views/groups-container/GroupsContainerView.types.ts index 3402bd99..0426ca8e 100644 --- a/src/views/user-profile/views/groups-container/GroupsContainerView.types.ts +++ b/src/views/user-profile/views/groups-container/GroupsContainerView.types.ts @@ -3,4 +3,5 @@ import { GroupDataParser } from '@nitrots/nitro-renderer'; export interface GroupsContainerViewProps { groups: GroupDataParser[]; + onLeaveGroup: () => void; } diff --git a/src/views/user-profile/views/user-container/UserContainerView.tsx b/src/views/user-profile/views/user-container/UserContainerView.tsx index a9f5456f..8d024a39 100644 --- a/src/views/user-profile/views/user-container/UserContainerView.tsx +++ b/src/views/user-profile/views/user-container/UserContainerView.tsx @@ -6,38 +6,38 @@ import { UserContainerViewProps } from './UserContainerView.types'; export const UserContainerView: FC = props => { - const { figure = null, username = null, motto = null, creation = null, secondsSinceLastLogin = null, achievementScore, isFriend = null, isOnline = null, id = null, requestSent = null } = props; + const { userProfile = null } = props; const OnlineIcon = useCallback(() => { - if(isOnline) return (); + if(userProfile.isOnline) return (); else return (); - }, [isOnline]); + }, [ userProfile ]); const FriendRequestComponent = useCallback(() => { - if(id === GetSessionDataManager().userId) return ({LocalizeText('extendedprofile.me')} ); + if(userProfile.id === GetSessionDataManager().userId) return ({LocalizeText('extendedprofile.me')} ); - if(isFriend) return ({LocalizeText('extendedprofile.friend')}); + if(userProfile.isMyFriend) return ({LocalizeText('extendedprofile.friend')}); - if(requestSent) return ({LocalizeText('extendedprofile.friendrequestsent')}); + if(userProfile.requestSent) return ({LocalizeText('extendedprofile.friendrequestsent')}); return () - }, [id, isFriend, requestSent]); + }, [ userProfile ]); return (
- +
-
{username}
-
{motto}
-
-
-
{LocalizeText('extendedprofile.achievementscore')} {achievementScore}
-
+
{userProfile.username}
+
{userProfile.motto}
+
+
+
{LocalizeText('extendedprofile.achievementscore')} {userProfile.achievementPoints}
+
diff --git a/src/views/user-profile/views/user-container/UserContainerView.types.ts b/src/views/user-profile/views/user-container/UserContainerView.types.ts index 9ef01c32..88df91d4 100644 --- a/src/views/user-profile/views/user-container/UserContainerView.types.ts +++ b/src/views/user-profile/views/user-container/UserContainerView.types.ts @@ -1,12 +1,6 @@ -export interface UserContainerViewProps { - id: number; - username: string; - figure: string; - motto: string; - creation: string; - secondsSinceLastLogin: number; - achievementScore: number; - isFriend: boolean; - requestSent: boolean; - isOnline: boolean; +import { UserProfileParser } from '@nitrots/nitro-renderer'; + +export interface UserContainerViewProps +{ + userProfile: UserProfileParser; } diff --git a/src/views/wired/WiredView.scss b/src/views/wired/WiredView.scss index ce1bc799..eba870c2 100644 --- a/src/views/wired/WiredView.scss +++ b/src/views/wired/WiredView.scss @@ -3,36 +3,52 @@ padding:7px; .icon { - width: 16px; - height: 9px; background-repeat: no-repeat; background-position: center; &.icon-mv-1 { + width: 16px; + height: 9px; background-image: url('../../assets/images/wired/icon_wired_around.png'); } &.icon-mv-2 { + width: 16px; + height: 9px; background-image: url('../../assets/images/wired/icon_wired_up_down.png'); } &.icon-mv-3 { + width: 16px; + height: 9px; background-image: url('../../assets/images/wired/icon_wired_left_right.png'); } &.icon-ne { + width: 16px; + height: 9px; background-image: url('../../assets/images/wired/icon_wired_north_east.png'); } &.icon-se { + width: 16px; + height: 9px; background-image: url('../../assets/images/wired/icon_wired_south_east.png'); } &.icon-sw { + width: 16px; + height: 9px; background-image: url('../../assets/images/wired/icon_wired_south_west.png'); } &.icon-nw { + width: 16px; + height: 9px; background-image: url('../../assets/images/wired/icon_wired_north_west.png'); } &.icon-rot-1 { + width: 16px; + height: 9px; background-image: url('../../assets/images/wired/icon_wired_rotate_clockwise.png'); } &.icon-rot-2 { + width: 16px; + height: 9px; background-image: url('../../assets/images/wired/icon_wired_rotate_counter_clockwise.png'); } }