diff --git a/src/components/groups/GroupsContext.tsx b/src/components/groups/GroupsContext.tsx new file mode 100644 index 00000000..19e20b8a --- /dev/null +++ b/src/components/groups/GroupsContext.tsx @@ -0,0 +1,20 @@ +import { createContext, Dispatch, FC, ProviderProps, useContext } from 'react'; +import { IGroupsAction, IGroupsState } from './reducers/GroupsReducer'; + +interface IGroupsContext +{ + groupsState: IGroupsState; + dispatchGroupsState: Dispatch; +} + +const GroupsContext = createContext({ + groupsState: null, + dispatchGroupsState: null +}); + +export const GroupsContextProvider: FC> = props => +{ + return { props.children } +} + +export const useGroupsContext = () => useContext(GroupsContext); diff --git a/src/components/groups/GroupsMessageHandler.tsx b/src/components/groups/GroupsMessageHandler.tsx index 0bb9e943..5e730da9 100644 --- a/src/components/groups/GroupsMessageHandler.tsx +++ b/src/components/groups/GroupsMessageHandler.tsx @@ -2,8 +2,8 @@ import { GroupBadgePartsEvent, GroupBuyDataEvent, GroupSettingsEvent, RoomCreate import { FC, useCallback } from 'react'; import { CreateMessageHook } from '../../hooks'; import { GroupBadgePart } from './common/GroupBadgePart'; -import { useGroupsContext } from './context/GroupsContext'; -import { GroupsActions } from './context/GroupsContext.types'; +import { useGroupsContext } from './GroupsContext'; +import { GroupsActions } from './reducers/GroupsReducer'; function compareId(a, b) { diff --git a/src/components/groups/GroupsView.tsx b/src/components/groups/GroupsView.tsx index 89300d77..2a2ec8b6 100644 --- a/src/components/groups/GroupsView.tsx +++ b/src/components/groups/GroupsView.tsx @@ -1,10 +1,10 @@ import { GroupBadgePartsComposer, GroupPurchasedEvent, GroupSettingsComposer, ILinkEventTracker } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useReducer, useState } from 'react'; import { AddEventLinkTracker, RemoveLinkEventTracker, TryVisitRoom } from '../../api'; -import { CreateMessageHook, SendMessageHook } from '../../hooks'; -import { GroupsContextProvider } from './context/GroupsContext'; -import { GroupsReducer, initialGroups } from './context/GroupsContext.types'; +import { BatchUpdates, CreateMessageHook, SendMessageHook } from '../../hooks'; +import { GroupsContextProvider } from './GroupsContext'; import { GroupsMessageHandler } from './GroupsMessageHandler'; +import { GroupsReducer, initialGroups } from './reducers/GroupsReducer'; import { GroupCreatorView } from './views/creator/GroupCreatorView'; import { GroupInformationStandaloneView } from './views/information-standalone/GroupInformationStandaloneView'; import { GroupManagerView } from './views/manager/GroupManagerView'; @@ -12,17 +12,30 @@ import { GroupMembersView } from './views/members/GroupMembersView'; export const GroupsView: FC<{}> = props => { - const [ groupsState, dispatchGroupsState ] = useReducer(GroupsReducer, initialGroups); - const [ isCreatorVisible, setIsCreatorVisible ] = useState(false); const [ groupMembersId, setGroupMembersId ] = useState(null); const [ groupMembersLevel, setGroupMembersLevel ] = useState(null); + const [ groupsState, dispatchGroupsState ] = useReducer(GroupsReducer, initialGroups); - useEffect(() => + const onGroupPurchasedEvent = useCallback((event: GroupPurchasedEvent) => { - SendMessageHook(new GroupBadgePartsComposer()); + const parser = event.getParser(); + + setIsCreatorVisible(false); + TryVisitRoom(parser.roomId); }, []); + CreateMessageHook(GroupPurchasedEvent, onGroupPurchasedEvent); + + const closeMembers = () => + { + BatchUpdates(() => + { + setGroupMembersId(null); + setGroupMembersLevel(null); + }); + } + const linkReceived = useCallback((url: string) => { const parts = url.split('/'); @@ -41,10 +54,13 @@ export const GroupsView: FC<{}> = props => return; case 'members': if(!parts[2]) return; - - setGroupMembersId(Number(parts[2])); - if(parts[3]) setGroupMembersLevel(Number(parts[3])); + BatchUpdates(() => + { + setGroupMembersId(Number(parts[2])); + + if(parts[3]) setGroupMembersLevel(Number(parts[3])); + }); return; } }, []); @@ -61,20 +77,9 @@ export const GroupsView: FC<{}> = props => return () => RemoveLinkEventTracker(linkTracker); }, [ linkReceived ]); - const onGroupPurchasedEvent = useCallback((event: GroupPurchasedEvent) => + useEffect(() => { - const parser = event.getParser(); - - setIsCreatorVisible(false); - TryVisitRoom(parser.roomId); - }, []); - - CreateMessageHook(GroupPurchasedEvent, onGroupPurchasedEvent); - - const closeMembers = useCallback(() => - { - setGroupMembersId(null); - setGroupMembersLevel(null); + SendMessageHook(new GroupBadgePartsComposer()); }, []); return ( diff --git a/src/components/groups/context/GroupsContext.tsx b/src/components/groups/context/GroupsContext.tsx deleted file mode 100644 index 27eb2078..00000000 --- a/src/components/groups/context/GroupsContext.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createContext, FC, useContext } from 'react'; -import { GroupsContextProps, IGroupsContext } from './GroupsContext.types'; - -const GroupsContext = createContext({ - groupsState: null, - dispatchGroupsState: null -}); - -export const GroupsContextProvider: FC = props => -{ - return { props.children } -} - -export const useGroupsContext = () => useContext(GroupsContext); diff --git a/src/components/groups/context/GroupsContext.types.ts b/src/components/groups/reducers/GroupsReducer.ts similarity index 95% rename from src/components/groups/context/GroupsContext.types.ts rename to src/components/groups/reducers/GroupsReducer.ts index ce95e62a..1889bf37 100644 --- a/src/components/groups/context/GroupsContext.types.ts +++ b/src/components/groups/reducers/GroupsReducer.ts @@ -1,17 +1,6 @@ -import { Dispatch, ProviderProps, Reducer } from 'react'; +import { Reducer } from 'react'; import { GroupBadgePart } from '../common/GroupBadgePart'; -export interface IGroupsContext -{ - groupsState: IGroupsState; - dispatchGroupsState: Dispatch; -} - -export interface GroupsContextProps extends ProviderProps -{ - -} - export interface IGroupsState { availableRooms: { id: number, name: string }[]; diff --git a/src/components/groups/views/creator/tab-confirmation/GroupCreatorTabConfirmationView.tsx b/src/components/groups/views/creator/GroupCreatorTabConfirmationView.tsx similarity index 92% rename from src/components/groups/views/creator/tab-confirmation/GroupCreatorTabConfirmationView.tsx rename to src/components/groups/views/creator/GroupCreatorTabConfirmationView.tsx index 351384e5..8b18520a 100644 --- a/src/components/groups/views/creator/tab-confirmation/GroupCreatorTabConfirmationView.tsx +++ b/src/components/groups/views/creator/GroupCreatorTabConfirmationView.tsx @@ -1,7 +1,7 @@ import { FC, useCallback } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { BadgeImageView } from '../../../../../views/shared/badge-image/BadgeImageView'; -import { useGroupsContext } from '../../../context/GroupsContext'; +import { LocalizeText } from '../../../../api'; +import { BadgeImageView } from '../../../../views/shared/badge-image/BadgeImageView'; +import { useGroupsContext } from '../../GroupsContext'; export const GroupCreatorTabConfirmationView: FC<{}> = props => { diff --git a/src/components/groups/views/creator/GroupCreatorView.tsx b/src/components/groups/views/creator/GroupCreatorView.tsx index 958b6138..53d68ae1 100644 --- a/src/components/groups/views/creator/GroupCreatorView.tsx +++ b/src/components/groups/views/creator/GroupCreatorView.tsx @@ -5,16 +5,21 @@ import { Button } from 'react-bootstrap'; import { HasHabboClub, LocalizeText } from '../../../../api'; import { SendMessageHook } from '../../../../hooks'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; -import { useGroupsContext } from '../../context/GroupsContext'; -import { GroupsActions } from '../../context/GroupsContext.types'; -import { GroupSharedTabBadgeView } from '../shared-tabs/tab-badge/GroupSharedTabBadgeView'; -import { GroupSharedTabColorsView } from '../shared-tabs/tab-colors/GroupSharedTabColorsView'; -import { GroupSharedTabIdentityView } from '../shared-tabs/tab-identity/GroupSharedTabIdentityView'; -import { GroupCreatorViewProps } from './GroupCreatorView.types'; -import { GroupCreatorTabConfirmationView } from './tab-confirmation/GroupCreatorTabConfirmationView'; +import { useGroupsContext } from '../../GroupsContext'; +import { GroupsActions } from '../../reducers/GroupsReducer'; +import { GroupSharedTabBadgeView } from '../shared-tabs/GroupSharedTabBadgeView'; +import { GroupSharedTabColorsView } from '../shared-tabs/GroupSharedTabColorsView'; +import { GroupSharedTabIdentityView } from '../shared-tabs/GroupSharedTabIdentityView'; +import { GroupCreatorTabConfirmationView } from './GroupCreatorTabConfirmationView'; const TABS: number[] = [1, 2, 3, 4]; +interface GroupCreatorViewProps +{ + isVisible: boolean; + onClose: () => void; +} + export const GroupCreatorView: FC = props => { const { groupsState = null, dispatchGroupsState = null } = useGroupsContext(); diff --git a/src/components/groups/views/creator/GroupCreatorView.types.ts b/src/components/groups/views/creator/GroupCreatorView.types.ts deleted file mode 100644 index 249f5dbf..00000000 --- a/src/components/groups/views/creator/GroupCreatorView.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface GroupCreatorViewProps -{ - isVisible: boolean; - onClose: () => void; -} diff --git a/src/components/groups/views/information/GroupInformationView.tsx b/src/components/groups/views/information/GroupInformationView.tsx index 58376380..00bc7272 100644 --- a/src/components/groups/views/information/GroupInformationView.tsx +++ b/src/components/groups/views/information/GroupInformationView.tsx @@ -1,4 +1,4 @@ -import { GroupRemoveMemberComposer } from '@nitrots/nitro-renderer'; +import { GroupInformationParser, GroupRemoveMemberComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback } from 'react'; import { CreateLinkEvent, GetSessionDataManager, LocalizeText, TryVisitRoom } from '../../../../api'; import { GetGroupManager } from '../../../../api/groups/GetGroupManager'; @@ -9,7 +9,13 @@ import { BadgeImageView } from '../../../../views/shared/badge-image/BadgeImageV import { CatalogPageName } from '../../../catalog/common/CatalogPageName'; import { GroupMembershipType } from '../../common/GroupMembershipType'; import { GroupType } from '../../common/GroupType'; -import { GroupInformationViewProps } from './GroupInformationView.types'; + +interface GroupInformationViewProps +{ + groupInformation: GroupInformationParser; + onJoin?: () => void; + onClose?: () => void; +} export const GroupInformationView: FC = props => { diff --git a/src/components/groups/views/information/GroupInformationView.types.ts b/src/components/groups/views/information/GroupInformationView.types.ts deleted file mode 100644 index 1d4abad6..00000000 --- a/src/components/groups/views/information/GroupInformationView.types.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { GroupInformationParser } from '@nitrots/nitro-renderer'; - -export interface GroupInformationViewProps -{ - groupInformation: GroupInformationParser; - onJoin?: () => void; - onClose?: () => void; -} diff --git a/src/components/groups/views/manager/GroupManagerView.tsx b/src/components/groups/views/manager/GroupManagerView.tsx index bb921122..11c21e4e 100644 --- a/src/components/groups/views/manager/GroupManagerView.tsx +++ b/src/components/groups/views/manager/GroupManagerView.tsx @@ -3,11 +3,11 @@ import { FC, useCallback, useState } from 'react'; import { LocalizeText } from '../../../../api'; import { SendMessageHook } from '../../../../hooks'; import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../layout'; -import { useGroupsContext } from '../../context/GroupsContext'; -import { GroupsActions } from '../../context/GroupsContext.types'; -import { GroupSharedTabBadgeView } from '../shared-tabs/tab-badge/GroupSharedTabBadgeView'; -import { GroupSharedTabColorsView } from '../shared-tabs/tab-colors/GroupSharedTabColorsView'; -import { GroupSharedTabIdentityView } from '../shared-tabs/tab-identity/GroupSharedTabIdentityView'; +import { useGroupsContext } from '../../GroupsContext'; +import { GroupsActions } from '../../reducers/GroupsReducer'; +import { GroupSharedTabBadgeView } from '../shared-tabs/GroupSharedTabBadgeView'; +import { GroupSharedTabColorsView } from '../shared-tabs/GroupSharedTabColorsView'; +import { GroupSharedTabIdentityView } from '../shared-tabs/GroupSharedTabIdentityView'; import { GroupManagerTabSettingsView } from './tab-settings/GroupManagerTabSettingsView'; const TABS: number[] = [1, 2, 3, 5]; diff --git a/src/components/groups/views/manager/tab-settings/GroupManagerTabSettingsView.tsx b/src/components/groups/views/manager/tab-settings/GroupManagerTabSettingsView.tsx index 27ea5f1c..8a2c7244 100644 --- a/src/components/groups/views/manager/tab-settings/GroupManagerTabSettingsView.tsx +++ b/src/components/groups/views/manager/tab-settings/GroupManagerTabSettingsView.tsx @@ -1,7 +1,7 @@ import { FC, useCallback } from 'react'; import { LocalizeText } from '../../../../../api/utils/LocalizeText'; -import { useGroupsContext } from '../../../context/GroupsContext'; -import { GroupsActions } from '../../../context/GroupsContext.types'; +import { useGroupsContext } from '../../../GroupsContext'; +import { GroupsActions } from '../../../reducers/GroupsReducer'; const STATES: string[] = ['regular', 'exclusive', 'private']; diff --git a/src/components/groups/views/members/GroupMembersView.tsx b/src/components/groups/views/members/GroupMembersView.tsx index 342e7869..69272784 100644 --- a/src/components/groups/views/members/GroupMembersView.tsx +++ b/src/components/groups/views/members/GroupMembersView.tsx @@ -6,7 +6,14 @@ import { CreateMessageHook, SendMessageHook } from '../../../../hooks'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; import { AvatarImageView } from '../../../../views/shared/avatar-image/AvatarImageView'; import { BadgeImageView } from '../../../../views/shared/badge-image/BadgeImageView'; -import { GroupMembersViewProps } from './GroupMembersView.types'; + +interface GroupMembersViewProps +{ + groupId: number; + levelId: number; + onClose: () => void; +} + export const GroupMembersView: FC = props => { diff --git a/src/components/groups/views/members/GroupMembersView.types.ts b/src/components/groups/views/members/GroupMembersView.types.ts deleted file mode 100644 index 44d151f6..00000000 --- a/src/components/groups/views/members/GroupMembersView.types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface GroupMembersViewProps -{ - groupId: number; - levelId: number; - onClose: () => void; -} diff --git a/src/components/groups/views/shared-tabs/tab-badge/GroupSharedTabBadgeView.tsx b/src/components/groups/views/shared-tabs/GroupSharedTabBadgeView.tsx similarity index 94% rename from src/components/groups/views/shared-tabs/tab-badge/GroupSharedTabBadgeView.tsx rename to src/components/groups/views/shared-tabs/GroupSharedTabBadgeView.tsx index cca52530..5e9fc7a5 100644 --- a/src/components/groups/views/shared-tabs/tab-badge/GroupSharedTabBadgeView.tsx +++ b/src/components/groups/views/shared-tabs/GroupSharedTabBadgeView.tsx @@ -1,13 +1,17 @@ import classNames from 'classnames'; import { FC, useCallback, useEffect, useState } from 'react'; -import { BadgeImageView } from '../../../../../views/shared/badge-image/BadgeImageView'; -import { GroupBadgePart } from '../../../common/GroupBadgePart'; -import { useGroupsContext } from '../../../context/GroupsContext'; -import { GroupsActions } from '../../../context/GroupsContext.types'; -import { GroupSharedTabBadgeViewProps } from './GroupSharedTabBadgeView.types'; +import { BadgeImageView } from '../../../../views/shared/badge-image/BadgeImageView'; +import { GroupBadgePart } from '../../common/GroupBadgePart'; +import { useGroupsContext } from '../../GroupsContext'; +import { GroupsActions } from '../../reducers/GroupsReducer'; const POSITIONS: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8]; +interface GroupSharedTabBadgeViewProps +{ + skipDefault?: boolean; +} + export const GroupSharedTabBadgeView: FC = props => { const { groupsState = null, dispatchGroupsState = null } = useGroupsContext(); diff --git a/src/components/groups/views/shared-tabs/tab-colors/GroupSharedTabColorsView.tsx b/src/components/groups/views/shared-tabs/GroupSharedTabColorsView.tsx similarity index 95% rename from src/components/groups/views/shared-tabs/tab-colors/GroupSharedTabColorsView.tsx rename to src/components/groups/views/shared-tabs/GroupSharedTabColorsView.tsx index 6040ca3c..490e8079 100644 --- a/src/components/groups/views/shared-tabs/tab-colors/GroupSharedTabColorsView.tsx +++ b/src/components/groups/views/shared-tabs/GroupSharedTabColorsView.tsx @@ -1,8 +1,8 @@ import classNames from 'classnames'; import { FC, useCallback, useEffect, useState } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { useGroupsContext } from '../../../context/GroupsContext'; -import { GroupsActions } from '../../../context/GroupsContext.types'; +import { LocalizeText } from '../../../../api'; +import { useGroupsContext } from '../../GroupsContext'; +import { GroupsActions } from '../../reducers/GroupsReducer'; export const GroupSharedTabColorsView: FC<{}> = props => { diff --git a/src/components/groups/views/shared-tabs/tab-identity/GroupSharedTabIdentityView.tsx b/src/components/groups/views/shared-tabs/GroupSharedTabIdentityView.tsx similarity index 90% rename from src/components/groups/views/shared-tabs/tab-identity/GroupSharedTabIdentityView.tsx rename to src/components/groups/views/shared-tabs/GroupSharedTabIdentityView.tsx index 78e4303a..7181a7d0 100644 --- a/src/components/groups/views/shared-tabs/tab-identity/GroupSharedTabIdentityView.tsx +++ b/src/components/groups/views/shared-tabs/GroupSharedTabIdentityView.tsx @@ -1,8 +1,12 @@ import { FC, useCallback } from 'react'; -import { CreateLinkEvent, LocalizeText } from '../../../../../api'; -import { useGroupsContext } from '../../../context/GroupsContext'; -import { GroupsActions } from '../../../context/GroupsContext.types'; -import { GroupSharedTabIdentityViewProps } from './GroupSharedTabIdentityView.types'; +import { CreateLinkEvent, LocalizeText } from '../../../../api'; +import { useGroupsContext } from '../../GroupsContext'; +import { GroupsActions } from '../../reducers/GroupsReducer'; + +interface GroupSharedTabIdentityViewProps +{ + isCreator?: boolean; +} export const GroupSharedTabIdentityView: FC = props => { diff --git a/src/components/groups/views/shared-tabs/GroupSharedTabs.scss b/src/components/groups/views/shared-tabs/GroupSharedTabs.scss index 4bf835ba..6c13623c 100644 --- a/src/components/groups/views/shared-tabs/GroupSharedTabs.scss +++ b/src/components/groups/views/shared-tabs/GroupSharedTabs.scss @@ -26,5 +26,54 @@ } } -@import './tab-badge/GroupSharedTabBadgeView'; -@import './tab-colors/GroupSharedTabColorsView'; +.shared-tab-badge { + .position-swatch { + position: relative; + border-radius: $border-radius; + width: 16px; + height: 16px; + background: $white; + border: 2px solid $white; + box-shadow: inset 3px 3px rgba(0, 0, 0, .1); + + &.active { + background: $primary; + box-shadow: none; + } + } + + .color-swatch { + position: relative; + border-radius: $border-radius; + width: 16px; + height: 16px; + border: 2px solid $white; + box-shadow: inset 3px 3px rgba(0, 0, 0, .1); + + &.active { + box-shadow: none; + } + } + + .selection-list { + height: 160px; + min-height: 160px; + max-height: 160px; + } +} + +.shared-tab-colors { + + .color-swatch { + position: relative; + border-radius: $border-radius; + width: 15px; + height: 15px; + border: 2px solid $white; + box-shadow: inset 2px 2px rgba(0, 0, 0, .2); + + &.active { + box-shadow: none; + } + } +} diff --git a/src/components/groups/views/shared-tabs/tab-badge/GroupSharedTabBadgeView.scss b/src/components/groups/views/shared-tabs/tab-badge/GroupSharedTabBadgeView.scss deleted file mode 100644 index 4475004d..00000000 --- a/src/components/groups/views/shared-tabs/tab-badge/GroupSharedTabBadgeView.scss +++ /dev/null @@ -1,35 +0,0 @@ -.shared-tab-badge { - .position-swatch { - position: relative; - border-radius: $border-radius; - width: 16px; - height: 16px; - background: $white; - border: 2px solid $white; - box-shadow: inset 3px 3px rgba(0, 0, 0, .1); - - &.active { - background: $primary; - box-shadow: none; - } - } - - .color-swatch { - position: relative; - border-radius: $border-radius; - width: 16px; - height: 16px; - border: 2px solid $white; - box-shadow: inset 3px 3px rgba(0, 0, 0, .1); - - &.active { - box-shadow: none; - } - } - - .selection-list { - height: 160px; - min-height: 160px; - max-height: 160px; - } -} diff --git a/src/components/groups/views/shared-tabs/tab-badge/GroupSharedTabBadgeView.types.ts b/src/components/groups/views/shared-tabs/tab-badge/GroupSharedTabBadgeView.types.ts deleted file mode 100644 index 75d04aab..00000000 --- a/src/components/groups/views/shared-tabs/tab-badge/GroupSharedTabBadgeView.types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface GroupSharedTabBadgeViewProps -{ - skipDefault?: boolean; -} diff --git a/src/components/groups/views/shared-tabs/tab-colors/GroupSharedTabColorsView.scss b/src/components/groups/views/shared-tabs/tab-colors/GroupSharedTabColorsView.scss deleted file mode 100644 index 80a94c75..00000000 --- a/src/components/groups/views/shared-tabs/tab-colors/GroupSharedTabColorsView.scss +++ /dev/null @@ -1,15 +0,0 @@ -.shared-tab-colors { - - .color-swatch { - position: relative; - border-radius: $border-radius; - width: 15px; - height: 15px; - border: 2px solid $white; - box-shadow: inset 2px 2px rgba(0, 0, 0, .2); - - &.active { - box-shadow: none; - } - } -} diff --git a/src/components/groups/views/shared-tabs/tab-identity/GroupSharedTabIdentityView.types.ts b/src/components/groups/views/shared-tabs/tab-identity/GroupSharedTabIdentityView.types.ts deleted file mode 100644 index d8648ac0..00000000 --- a/src/components/groups/views/shared-tabs/tab-identity/GroupSharedTabIdentityView.types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface GroupSharedTabIdentityViewProps -{ - isCreator?: boolean; -}