diff --git a/src/api/groups/GetGroupManager.ts b/src/api/groups/GetGroupManager.ts
new file mode 100644
index 00000000..bd5a6c70
--- /dev/null
+++ b/src/api/groups/GetGroupManager.ts
@@ -0,0 +1,6 @@
+import { CreateLinkEvent } from '..';
+
+export function GetGroupManager(groupId: number): void
+{
+ CreateLinkEvent(`groups/manage/${groupId}`);
+}
diff --git a/src/views/groups/GroupView.scss b/src/views/groups/GroupView.scss
index 354f6406..daaaf82c 100644
--- a/src/views/groups/GroupView.scss
+++ b/src/views/groups/GroupView.scss
@@ -1,5 +1,53 @@
+.nitro-groups {
+ .tab-image {
+ width: 122px;
+ height: 68px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ div {
+ background-image: url('../../assets/images/groups/creator_images.png');
+ background-repeat: no-repeat;
+ }
+
+ &.tab-1 {
+ div {
+ background-position: 0px 0px;
+ width: 99px;
+ height: 50px;
+ }
+ }
+
+ &.tab-2 {
+ div {
+ background-position: -99px 0px;
+ width: 98px;
+ height: 62px;
+ }
+ }
+
+ &.tab-3 {
+ div {
+ background-position: 0px -50px;
+ width: 96px;
+ height: 45px;
+ }
+ }
+
+ &.tab-4, &.tab-5 {
+ div {
+ background-position: 0px -95px;
+ width: 114px;
+ height: 61px;
+ }
+ }
+ }
+}
+
@import './views/creator/GroupCreatorView';
@import './views/information/GroupInformationView';
@import './views/information-standalone/GroupInformationStandaloneView';
+@import './views/manager/GroupManagerView';
@import './views/room-information/GroupRoomInformationView';
@import './views/shared-tabs/GroupSharedTabs';
diff --git a/src/views/groups/GroupsMessageHandler.tsx b/src/views/groups/GroupsMessageHandler.tsx
index 2a57ca9d..efa2b1bf 100644
--- a/src/views/groups/GroupsMessageHandler.tsx
+++ b/src/views/groups/GroupsMessageHandler.tsx
@@ -1,6 +1,7 @@
-import { GroupBadgePartsEvent, GroupBuyDataEvent, RoomCreatedEvent } from '@nitrots/nitro-renderer';
+import { GroupBadgePartsEvent, GroupBuyDataEvent, GroupSettingsEvent, RoomCreatedEvent } from '@nitrots/nitro-renderer';
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';
@@ -30,8 +31,8 @@ export const GroupsMessageHandler: FC<{}> = props =>
dispatchGroupsState({
type: GroupsActions.SET_PURHCASE_SETTINGS,
payload: {
- objectArrays: rooms,
- numberValue: parser.groupCost
+ objectValues: rooms,
+ numberValues: [ parser.groupCost ]
}
});
}, [ dispatchGroupsState ]);
@@ -50,11 +51,10 @@ export const GroupsMessageHandler: FC<{}> = props =>
dispatchGroupsState({
type: GroupsActions.SET_PURHCASE_SETTINGS,
payload: {
- objectArrays: clonedRooms
+ objectValues: clonedRooms
}
});
- }, []);
-
+ }, [ availableRooms, dispatchGroupsState ]);
const onGroupBadgePartsEvent = useCallback((event: GroupBadgePartsEvent) =>
{
@@ -100,14 +100,42 @@ export const GroupsMessageHandler: FC<{}> = props =>
dispatchGroupsState({
type: GroupsActions.SET_GROUP_BADGE_PARTS_CONFIG,
payload: {
- objectArrays: [ bases, symbols, partColors, colorsA, colorsB ]
+ objectValues: [ bases, symbols, partColors, colorsA, colorsB ]
}
- })
+ });
+ }, [ dispatchGroupsState ]);
+
+ const onGroupSettingsEvent = useCallback((event: GroupSettingsEvent) =>
+ {
+ const parser = event.getParser();
+
+ const groupBadgeParts: GroupBadgePart[] = [];
+
+ parser.badgeParts.forEach((part, id) =>
+ {
+ groupBadgeParts.push(new GroupBadgePart(
+ part.isBase ? GroupBadgePart.BASE : part.key >= 100 ? GroupBadgePart.SYMBOL_ALT : GroupBadgePart.SYMBOL,
+ part.key >= 100 ? part.key - 100 : part.key,
+ part.color,
+ part.position
+ ));
+ });
+
+ dispatchGroupsState({
+ type: GroupsActions.SET_GROUP_SETTINGS,
+ payload: {
+ stringValues: [ parser.title, parser.description ],
+ numberValues: [ parser.id, parser.state, parser.colorA, parser.colorB ],
+ boolValues: [ parser.canMembersDecorate ],
+ objectValues: groupBadgeParts
+ }
+ });
}, [ dispatchGroupsState ]);
CreateMessageHook(GroupBuyDataEvent, onGroupBuyDataEvent);
CreateMessageHook(RoomCreatedEvent, onRoomCreatedEvent);
CreateMessageHook(GroupBadgePartsEvent, onGroupBadgePartsEvent);
+ CreateMessageHook(GroupSettingsEvent, onGroupSettingsEvent);
return null;
};
diff --git a/src/views/groups/GroupsView.tsx b/src/views/groups/GroupsView.tsx
index e4b9af32..1598c276 100644
--- a/src/views/groups/GroupsView.tsx
+++ b/src/views/groups/GroupsView.tsx
@@ -1,4 +1,4 @@
-import { GroupBadgePartsComposer, GroupPurchasedEvent, ILinkEventTracker } from '@nitrots/nitro-renderer';
+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';
@@ -7,6 +7,7 @@ import { GroupsReducer, initialGroups } from './context/GroupsContext.types';
import { GroupsMessageHandler } from './GroupsMessageHandler';
import { GroupCreatorView } from './views/creator/GroupCreatorView';
import { GroupInformationStandaloneView } from './views/information-standalone/GroupInformationStandaloneView';
+import { GroupManagerView } from './views/manager/GroupManagerView';
export const GroupsView: FC<{}> = props =>
{
@@ -30,6 +31,11 @@ export const GroupsView: FC<{}> = props =>
case 'create':
setIsCreatorVisible(true);
return;
+ case 'manage':
+ if(!parts[2]) return;
+
+ SendMessageHook(new GroupSettingsComposer(Number(parts[2])));
+ return;
}
}, []);
@@ -60,6 +66,7 @@ export const GroupsView: FC<{}> = props =>
setIsCreatorVisible(false) } />
+
diff --git a/src/views/groups/context/GroupsContext.types.ts b/src/views/groups/context/GroupsContext.types.ts
index 210d9cd2..ac4fa922 100644
--- a/src/views/groups/context/GroupsContext.types.ts
+++ b/src/views/groups/context/GroupsContext.types.ts
@@ -19,6 +19,7 @@ export interface IGroupsState
badgeBases: { id: number, images: string[] }[];
badgeSymbols: { id: number, images: string[] }[];
badgePartColors: { id: number, color: string }[];
+ groupId: number;
groupColorsA: { id: number, color: string }[];
groupColorsB: { id: number, color: string }[];
groupName: string;
@@ -26,15 +27,18 @@ export interface IGroupsState
groupHomeroomId: number;
groupBadgeParts: GroupBadgePart[];
groupColors: number[];
+ groupState: number;
+ groupCanMembersDecorate: boolean;
}
export interface IGroupsAction
{
type: string;
payload?: {
- objectArrays?: any[];
- stringValue?: string;
- numberValue?: number;
+ objectValues?: any[];
+ stringValues?: string[];
+ numberValues?: number[];
+ boolValues?: boolean[];
badgeParts?: GroupBadgePart[];
}
}
@@ -48,6 +52,9 @@ export class GroupsActions
public static SET_GROUP_HOMEROOM_ID: string = 'GA_SET_GROUP_HOMEROOM_ID';
public static SET_GROUP_BADGE_PARTS: string = 'GA_SET_BADGE_PARTS';
public static SET_GROUP_COLORS: string = 'GA_SET_GROUP_COLORS';
+ public static SET_GROUP_STATE: string = 'GA_SET_GROUP_STATE';
+ public static SET_GROUP_CAN_MEMBERS_DECORATE: string = 'GA_SET_GROUP_CAN_MEMBERS_DECORATE';
+ public static SET_GROUP_SETTINGS: string = 'GA_SET_GROUP_SETTINGS';
public static RESET_GROUP_SETTINGS: string = 'GA_RESET_GROUP_SETTINGS';
}
@@ -57,13 +64,16 @@ export const initialGroups: IGroupsState = {
badgeBases: null,
badgeSymbols: null,
badgePartColors: null,
+ groupId: null,
groupColorsA: null,
groupColorsB: null,
groupName: '',
groupDescription: '',
groupHomeroomId: 0,
groupBadgeParts: null,
- groupColors: null
+ groupColors: null,
+ groupState: null,
+ groupCanMembersDecorate: null
};
export const GroupsReducer: Reducer = (state, action) =>
@@ -71,32 +81,32 @@ export const GroupsReducer: Reducer = (state, actio
switch(action.type)
{
case GroupsActions.SET_PURHCASE_SETTINGS: {
- const availableRooms = action.payload.objectArrays;
- const purchaseCost = (action.payload.numberValue || state.purchaseCost || 0);
+ const availableRooms = action.payload.objectValues;
+ const purchaseCost = (action.payload.numberValues[0] || state.purchaseCost || 0);
return { ...state, availableRooms, purchaseCost };
}
case GroupsActions.SET_GROUP_BADGE_PARTS_CONFIG: {
- const badgeBases = (action.payload.objectArrays[0] || state.badgeBases || null);
- const badgeSymbols = (action.payload.objectArrays[1] || state.badgeSymbols || null);
- const badgePartColors = (action.payload.objectArrays[2] || state.badgePartColors || null);
- const groupColorsA = (action.payload.objectArrays[3] || state.groupColorsA || null);
- const groupColorsB = (action.payload.objectArrays[4] || state.groupColorsB || null);
+ const badgeBases = (action.payload.objectValues[0] || state.badgeBases || null);
+ const badgeSymbols = (action.payload.objectValues[1] || state.badgeSymbols || null);
+ const badgePartColors = (action.payload.objectValues[2] || state.badgePartColors || null);
+ const groupColorsA = (action.payload.objectValues[3] || state.groupColorsA || null);
+ const groupColorsB = (action.payload.objectValues[4] || state.groupColorsB || null);
return { ...state, badgeBases, badgeSymbols, badgePartColors, groupColorsA, groupColorsB };
}
case GroupsActions.SET_GROUP_NAME: {
- const groupName = action.payload.stringValue;
+ const groupName = action.payload.stringValues[0];
return { ...state, groupName };
}
case GroupsActions.SET_GROUP_DESCRIPTION: {
- const groupDescription = action.payload.stringValue;
+ const groupDescription = action.payload.stringValues[0];
return { ...state, groupDescription };
}
case GroupsActions.SET_GROUP_HOMEROOM_ID: {
- const groupHomeroomId = action.payload.numberValue;
+ const groupHomeroomId = action.payload.numberValues[0];
return { ...state, groupHomeroomId };
}
@@ -106,18 +116,42 @@ export const GroupsReducer: Reducer = (state, actio
return { ...state, groupBadgeParts };
}
case GroupsActions.SET_GROUP_COLORS: {
- const groupColors = action.payload.objectArrays;
+ const groupColors = action.payload.objectValues;
return { ...state, groupColors };
}
+ case GroupsActions.SET_GROUP_STATE: {
+ const groupState = action.payload.numberValues[0];
+
+ return { ...state, groupState };
+ }
+ case GroupsActions.SET_GROUP_CAN_MEMBERS_DECORATE: {
+ const groupCanMembersDecorate = action.payload.boolValues[0];
+
+ return { ...state, groupCanMembersDecorate };
+ }
+ case GroupsActions.SET_GROUP_SETTINGS: {
+ const groupId = action.payload.numberValues[0];
+ const groupName = action.payload.stringValues[0];
+ const groupDescription = action.payload.stringValues[1];
+ const groupBadgeParts = action.payload.objectValues;
+ const groupState = action.payload.numberValues[1];
+ const groupColors = action.payload.numberValues.slice(2);
+ const groupCanMembersDecorate = action.payload.boolValues[0];
+
+ return { ...state, groupId, groupName, groupDescription, groupBadgeParts, groupColors, groupState, groupCanMembersDecorate };
+ }
case GroupsActions.RESET_GROUP_SETTINGS: {
+ const groupId = null;
const groupName = '';
const groupDescription = '';
const groupHomeroomId = 0;
const groupBadgeParts = null;
const groupColors = null;
+ const groupState = null;
+ const groupCanMembersDecorate = null;
- return { ...state, groupName, groupDescription, groupHomeroomId, groupBadgeParts, groupColors };
+ return { ...state, groupId, groupName, groupDescription, groupHomeroomId, groupBadgeParts, groupColors, groupState, groupCanMembersDecorate };
}
default:
return state;
diff --git a/src/views/groups/views/creator/GroupCreatorView.scss b/src/views/groups/views/creator/GroupCreatorView.scss
index df40ce78..8cecc536 100644
--- a/src/views/groups/views/creator/GroupCreatorView.scss
+++ b/src/views/groups/views/creator/GroupCreatorView.scss
@@ -68,51 +68,6 @@
}
}
- .tab-image {
- width: 122px;
- height: 68px;
- display: flex;
- align-items: center;
- justify-content: center;
-
- div {
- background-image: url('../../../../assets/images/groups/creator_images.png');
- background-repeat: no-repeat;
- }
-
- &.tab-1 {
- div {
- background-position: 0px 0px;
- width: 99px;
- height: 50px;
- }
- }
-
- &.tab-2 {
- div {
- background-position: -99px 0px;
- width: 98px;
- height: 62px;
- }
- }
-
- &.tab-3 {
- div {
- background-position: 0px -50px;
- width: 96px;
- height: 45px;
- }
- }
-
- &.tab-4 {
- div {
- background-position: 0px -95px;
- width: 114px;
- height: 61px;
- }
- }
- }
-
.creator-tab {
height: 230px;
min-height: 230px;
diff --git a/src/views/groups/views/creator/GroupCreatorView.tsx b/src/views/groups/views/creator/GroupCreatorView.tsx
index 10a23970..958b6138 100644
--- a/src/views/groups/views/creator/GroupCreatorView.tsx
+++ b/src/views/groups/views/creator/GroupCreatorView.tsx
@@ -9,9 +9,9 @@ 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 './views/tab-confirmation/GroupCreatorTabConfirmationView';
-import { GroupCreatorTabIdentityView } from './views/tab-identity/GroupCreatorTabIdentityView';
+import { GroupCreatorTabConfirmationView } from './tab-confirmation/GroupCreatorTabConfirmationView';
const TABS: number[] = [1, 2, 3, 4];
@@ -113,7 +113,7 @@ export const GroupCreatorView: FC = props =>
- { currentTab === 1 &&
}
+ { currentTab === 1 &&
}
{ currentTab === 2 &&
}
{ currentTab === 3 &&
}
{ currentTab === 4 &&
}
diff --git a/src/views/groups/views/creator/views/tab-confirmation/GroupCreatorTabConfirmationView.tsx b/src/views/groups/views/creator/tab-confirmation/GroupCreatorTabConfirmationView.tsx
similarity index 92%
rename from src/views/groups/views/creator/views/tab-confirmation/GroupCreatorTabConfirmationView.tsx
rename to src/views/groups/views/creator/tab-confirmation/GroupCreatorTabConfirmationView.tsx
index 4fc01ae9..d0ef989f 100644
--- a/src/views/groups/views/creator/views/tab-confirmation/GroupCreatorTabConfirmationView.tsx
+++ b/src/views/groups/views/creator/tab-confirmation/GroupCreatorTabConfirmationView.tsx
@@ -1,7 +1,7 @@
import { FC, useCallback } from 'react';
-import { LocalizeText } from '../../../../../../api';
-import { BadgeImageView } from '../../../../../shared/badge-image/BadgeImageView';
-import { useGroupsContext } from '../../../../context/GroupsContext';
+import { LocalizeText } from '../../../../../api';
+import { BadgeImageView } from '../../../../shared/badge-image/BadgeImageView';
+import { useGroupsContext } from '../../../context/GroupsContext';
export const GroupCreatorTabConfirmationView: FC<{}> = props =>
{
diff --git a/src/views/groups/views/information/GroupInformationView.tsx b/src/views/groups/views/information/GroupInformationView.tsx
index 8f13cf28..e550a3ba 100644
--- a/src/views/groups/views/information/GroupInformationView.tsx
+++ b/src/views/groups/views/information/GroupInformationView.tsx
@@ -1,6 +1,7 @@
-import { GroupDeleteComposer, GroupRemoveMemberComposer } from '@nitrots/nitro-renderer';
+import { GroupRemoveMemberComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback } from 'react';
import { CreateLinkEvent, GetSessionDataManager, LocalizeText, TryVisitRoom } from '../../../../api';
+import { GetGroupManager } from '../../../../api/groups/GetGroupManager';
import { TryJoinGroup } from '../../../../api/groups/TryJoinGroup';
import { SendMessageHook } from '../../../../hooks';
import { CatalogPageName } from '../../../catalog/common/CatalogPageName';
@@ -81,13 +82,6 @@ export const GroupInformationView: FC
= props =>
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 ]);
@@ -96,26 +90,22 @@ export const GroupInformationView: FC = props =>
return (
-
-
-
-
- { LocalizeText('group.membercount', ['totalMembers'], [groupInformation.membersCount.toString()]) }
-
+
+
+
-
@@ -126,20 +116,16 @@ export const GroupInformationView: FC = props =>
{ LocalizeText('group.created', ['date', 'owner'], [groupInformation.createdAt, groupInformation.ownerName]) }
{ groupInformation.description }
-
-
handleAction('homeroom') }>
+
+
handleAction('homeroom') }>
{ LocalizeText('group.linktobase') }
-
-
-
+
handleAction('furniture') }>
{ LocalizeText('group.buyfurni') }
-
-
-
+
{ LocalizeText('group.showgroups') }
-
+
{ groupInformation.type !== GroupType.PRIVATE &&
-
-
-
-
-
{ LocalizeText('group.edit.base.warning') }
-
CreateLinkEvent('navigator/create') }>{ LocalizeText('group.createroom') }
+ { isCreator && <>
+
+
+
+
+
{ LocalizeText('group.edit.base.warning') }
+
CreateLinkEvent('navigator/create') }>{ LocalizeText('group.createroom') }
+ > }
);
};
diff --git a/src/views/groups/views/shared-tabs/tab-identity/GroupSharedTabIdentityView.types.ts b/src/views/groups/views/shared-tabs/tab-identity/GroupSharedTabIdentityView.types.ts
new file mode 100644
index 00000000..d8648ac0
--- /dev/null
+++ b/src/views/groups/views/shared-tabs/tab-identity/GroupSharedTabIdentityView.types.ts
@@ -0,0 +1,4 @@
+export interface GroupSharedTabIdentityViewProps
+{
+ isCreator?: boolean;
+}