mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-30 00:50:50 +01:00
Update more components
This commit is contained in:
parent
e7112a9e07
commit
81fab26a1b
@ -1,5 +1,5 @@
|
||||
import { AvatarFigurePartType, IAvatarImageListener, IAvatarRenderManager, IFigurePart, IFigurePartSet, IGraphicAsset, IPartColor, NitroAlphaFilter, NitroContainer, NitroSprite, TextureUtils } from '@nitrots/nitro-renderer';
|
||||
import { GetAvatarRenderManager } from '../../../api';
|
||||
import { GetAvatarRenderManager } from '../nitro';
|
||||
import { FigureData } from './FigureData';
|
||||
|
||||
export class AvatarEditorGridPartItem implements IAvatarImageListener
|
@ -1,5 +1,5 @@
|
||||
import { IPartColor } from '@nitrots/nitro-renderer';
|
||||
import { GetAvatarPalette, GetAvatarRenderManager, GetAvatarSetType, GetClubMemberLevel, GetConfiguration } from '../../../api';
|
||||
import { GetAvatarPalette, GetAvatarRenderManager, GetAvatarSetType, GetClubMemberLevel, GetConfiguration } from '../nitro';
|
||||
import { AvatarEditorGridColorItem } from './AvatarEditorGridColorItem';
|
||||
import { AvatarEditorGridPartItem } from './AvatarEditorGridPartItem';
|
||||
import { CategoryBaseModel } from './CategoryBaseModel';
|
@ -1,5 +1,5 @@
|
||||
import { AvatarEditorFigureCategory, AvatarScaleType, AvatarSetType } from '@nitrots/nitro-renderer';
|
||||
import { GetAvatarRenderManager } from '../../../api';
|
||||
import { GetAvatarRenderManager } from '../nitro';
|
||||
import { AvatarEditorUtilities } from './AvatarEditorUtilities';
|
||||
import { CategoryBaseModel } from './CategoryBaseModel';
|
||||
import { FigureData } from './FigureData';
|
@ -1,6 +1,6 @@
|
||||
import { AvatarFigureContainer, IFigurePartSet, IPalette, IPartColor, SetType } from '@nitrots/nitro-renderer';
|
||||
import { GetAvatarRenderManager } from '../../../api';
|
||||
import { Randomizer } from '../../../api/utils';
|
||||
import { GetAvatarRenderManager } from '../nitro';
|
||||
import { Randomizer } from '../utils';
|
||||
import { FigureData } from './FigureData';
|
||||
|
||||
function getTotalColors(partSet: IFigurePartSet): number
|
13
src/api/avatar/index.ts
Normal file
13
src/api/avatar/index.ts
Normal file
@ -0,0 +1,13 @@
|
||||
export * from './AvatarEditorAction';
|
||||
export * from './AvatarEditorGridColorItem';
|
||||
export * from './AvatarEditorGridPartItem';
|
||||
export * from './AvatarEditorUtilities';
|
||||
export * from './BodyModel';
|
||||
export * from './CategoryBaseModel';
|
||||
export * from './CategoryData';
|
||||
export * from './FigureData';
|
||||
export * from './FigureGenerator';
|
||||
export * from './HeadModel';
|
||||
export * from './IAvatarEditorCategoryModel';
|
||||
export * from './LegModel';
|
||||
export * from './TorsoModel';
|
3
src/api/camera/index.ts
Normal file
3
src/api/camera/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './CameraEditorTabs';
|
||||
export * from './CameraPicture';
|
||||
export * from './CameraPictureThumbnail';
|
@ -1,5 +1,6 @@
|
||||
export const currentDate = () =>
|
||||
export const ChatHistoryCurrentDate = () =>
|
||||
{
|
||||
const currentTime = new Date();
|
||||
|
||||
return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`;
|
||||
}
|
5
src/api/chat-history/IRoomHistoryEntry.ts
Normal file
5
src/api/chat-history/IRoomHistoryEntry.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface IRoomHistoryEntry
|
||||
{
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
4
src/api/chat-history/index.ts
Normal file
4
src/api/chat-history/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './ChatEntryType';
|
||||
export * from './ChatHistoryCurrentDate';
|
||||
export * from './IChatEntry';
|
||||
export * from './IRoomHistoryEntry';
|
@ -1,4 +1,4 @@
|
||||
export class GroupType
|
||||
export class MessengerGroupType
|
||||
{
|
||||
public static readonly GROUP_CHAT = 0;
|
||||
public static readonly PRIVATE_CHAT = 1;
|
@ -1,7 +1,7 @@
|
||||
import { LocalizeText } from '../utils';
|
||||
import { GetGroupChatData } from './GetGroupChatData';
|
||||
import { GroupType } from './GroupType';
|
||||
import { MessengerFriend } from './MessengerFriend';
|
||||
import { MessengerGroupType } from './MessengerGroupType';
|
||||
import { MessengerThreadChat } from './MessengerThreadChat';
|
||||
import { MessengerThreadChatGroup } from './MessengerThreadChatGroup';
|
||||
|
||||
@ -41,7 +41,7 @@ export class MessengerThread
|
||||
|
||||
if(!group) return;
|
||||
|
||||
if(isGroupChat) group.type = GroupType.GROUP_CHAT;
|
||||
if(isGroupChat) group.type = MessengerGroupType.GROUP_CHAT;
|
||||
|
||||
const chat = new MessengerThreadChat(senderId, message, secondsSinceSent, extraData, type);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GroupType } from './GroupType';
|
||||
import { MessengerGroupType } from './MessengerGroupType';
|
||||
import { MessengerThreadChat } from './MessengerThreadChat';
|
||||
|
||||
export class MessengerThreadChatGroup
|
||||
@ -7,7 +7,7 @@ export class MessengerThreadChatGroup
|
||||
private _chats: MessengerThreadChat[];
|
||||
private _type: number;
|
||||
|
||||
constructor(userId: number, type = GroupType.PRIVATE_CHAT)
|
||||
constructor(userId: number, type = MessengerGroupType.PRIVATE_CHAT)
|
||||
{
|
||||
this._userId = userId;
|
||||
this._chats = [];
|
||||
|
@ -1,7 +1,7 @@
|
||||
export * from './GetGroupChatData';
|
||||
export * from './GroupType';
|
||||
export * from './IGroupChatData';
|
||||
export * from './MessengerFriend';
|
||||
export * from './MessengerGroupType';
|
||||
export * from './MessengerIconState';
|
||||
export * from './MessengerRequest';
|
||||
export * from './MessengerSettings';
|
||||
|
@ -1,5 +1,10 @@
|
||||
export * from './GetGroupInformation';
|
||||
export * from './GetGroupManager';
|
||||
export * from './GetGroupMembers';
|
||||
export * from './GroupBadgePart';
|
||||
export * from './GroupMembershipType';
|
||||
export * from './GroupType';
|
||||
export * from './IGroupCustomize';
|
||||
export * from './IGroupData';
|
||||
export * from './ToggleFavoriteGroup';
|
||||
export * from './TryJoinGroup';
|
||||
|
3
src/api/guide-tool/index.ts
Normal file
3
src/api/guide-tool/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './GuideSessionState';
|
||||
export * from './GuideToolMessage';
|
||||
export * from './GuideToolMessageGroup';
|
@ -1,4 +1,4 @@
|
||||
import { IChatEntry } from '../../chat-history/common/IChatEntry';
|
||||
import { IChatEntry } from '../chat-history';
|
||||
|
||||
export interface IHelpReportState
|
||||
{
|
4
src/api/help/index.ts
Normal file
4
src/api/help/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './CallForHelpResult';
|
||||
export * from './GetCloseReasonKey';
|
||||
export * from './IHelpReportState';
|
||||
export * from './IReportedUser';
|
@ -1,12 +1,17 @@
|
||||
export * from './achievements';
|
||||
export * from './avatar';
|
||||
export * from './camera';
|
||||
export * from './campaign';
|
||||
export * from './catalog';
|
||||
export * from './chat-history';
|
||||
export * from './events';
|
||||
export * from './friends';
|
||||
export * from './GetRendererVersion';
|
||||
export * from './GetUIVersion';
|
||||
export * from './groups';
|
||||
export * from './guide-tool';
|
||||
export * from './hc-center';
|
||||
export * from './help';
|
||||
export * from './inventory';
|
||||
export * from './navigator';
|
||||
export * from './nitro';
|
||||
|
@ -1,4 +1,4 @@
|
||||
export class WiredActionLayout
|
||||
export class WiredActionLayoutCode
|
||||
{
|
||||
public static TOGGLE_FURNI_STATE: number = 0;
|
||||
public static RESET: number = 1;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { NitroRectangle, NitroRenderTexture } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useRef } from 'react';
|
||||
import { GetRoomEngine, LocalizeText, SoundNames } from '../../api';
|
||||
import { PlaySound } from '../../api/utils/PlaySound';
|
||||
import { GetRoomEngine, LocalizeText, PlaySound, SoundNames } from '../../api';
|
||||
import { DraggableWindow } from '../draggable-window';
|
||||
|
||||
interface LayoutMiniCameraViewProps
|
||||
|
@ -1,25 +1,12 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { AvatarEditorFigureCategory, FigureSetIdsMessageEvent, GetWardrobeMessageComposer, IAvatarFigureContainer, ILinkEventTracker, UserFigureComposer, UserWardrobePageEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { AddEventLinkTracker, GetAvatarRenderManager, GetClubMemberLevel, GetConfiguration, GetSessionDataManager, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
|
||||
import { Button } from '../../common/Button';
|
||||
import { ButtonGroup } from '../../common/ButtonGroup';
|
||||
import { Column } from '../../common/Column';
|
||||
import { Grid } from '../../common/Grid';
|
||||
import { AddEventLinkTracker, AvatarEditorAction, AvatarEditorUtilities, BodyModel, FigureData, generateRandomFigure, GetAvatarRenderManager, GetClubMemberLevel, GetConfiguration, GetSessionDataManager, HeadModel, IAvatarEditorCategoryModel, LegModel, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TorsoModel } from '../../api';
|
||||
import { Button, ButtonGroup, Column, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
|
||||
import { useMessageEvent } from '../../hooks';
|
||||
import { AvatarEditorAction } from './common/AvatarEditorAction';
|
||||
import { AvatarEditorUtilities } from './common/AvatarEditorUtilities';
|
||||
import { BodyModel } from './common/BodyModel';
|
||||
import { FigureData } from './common/FigureData';
|
||||
import { generateRandomFigure } from './common/FigureGenerator';
|
||||
import { HeadModel } from './common/HeadModel';
|
||||
import { IAvatarEditorCategoryModel } from './common/IAvatarEditorCategoryModel';
|
||||
import { LegModel } from './common/LegModel';
|
||||
import { TorsoModel } from './common/TorsoModel';
|
||||
import { AvatarEditorFigurePreviewView } from './views/figure-preview/AvatarEditorFigurePreviewView';
|
||||
import { AvatarEditorModelView } from './views/model/AvatarEditorModelView';
|
||||
import { AvatarEditorWardrobeView } from './views/wardrobe/AvatarEditorWardrobeView';
|
||||
import { AvatarEditorFigurePreviewView } from './views/AvatarEditorFigurePreviewView';
|
||||
import { AvatarEditorModelView } from './views/AvatarEditorModelView';
|
||||
import { AvatarEditorWardrobeView } from './views/AvatarEditorWardrobeView';
|
||||
|
||||
const DEFAULT_MALE_FIGURE: string = 'hr-100.hd-180-7.ch-215-66.lg-270-79.sh-305-62.ha-1002-70.wa-2007';
|
||||
const DEFAULT_FEMALE_FIGURE: string = 'hr-515-33.hd-600-1.ch-635-70.lg-716-66-62.sh-735-68';
|
||||
@ -42,17 +29,15 @@ export const AvatarEditorView: FC<{}> = props =>
|
||||
|
||||
const maxWardrobeSlots = useMemo(() => GetConfiguration<number>('avatar.wardrobe.max.slots', 10), []);
|
||||
|
||||
const onFigureSetIdsMessageEvent = useCallback((event: FigureSetIdsMessageEvent) =>
|
||||
useMessageEvent<FigureSetIdsMessageEvent>(FigureSetIdsMessageEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setFigureSetIds(parser.figureSetIds);
|
||||
setBoundFurnitureNames(parser.boundsFurnitureNames);
|
||||
}, []);
|
||||
});
|
||||
|
||||
useMessageEvent(FigureSetIdsMessageEvent, onFigureSetIdsMessageEvent);
|
||||
|
||||
const onUserWardrobePageEvent = useCallback((event: UserWardrobePageEvent) =>
|
||||
useMessageEvent<UserWardrobePageEvent>(UserWardrobePageEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
const savedFigures: [ IAvatarFigureContainer, string ][] = [];
|
||||
@ -73,10 +58,8 @@ export const AvatarEditorView: FC<{}> = props =>
|
||||
savedFigures[(index - 1)] = [ container, gender ];
|
||||
}
|
||||
|
||||
setSavedFigures(savedFigures)
|
||||
}, [ maxWardrobeSlots ]);
|
||||
|
||||
useMessageEvent(UserWardrobePageEvent, onUserWardrobePageEvent);
|
||||
setSavedFigures(savedFigures);
|
||||
});
|
||||
|
||||
const selectCategory = useCallback((name: string) =>
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { AvatarDirectionAngle } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { Base, Column, LayoutAvatarImageView } from '../../../../common';
|
||||
import { FigureData } from '../../common/FigureData';
|
||||
import { AvatarEditorIcon } from '../AvatarEditorIcon';
|
||||
import { FigureData } from '../../../api';
|
||||
import { Base, Column, LayoutAvatarImageView } from '../../../common';
|
||||
import { AvatarEditorIcon } from './AvatarEditorIcon';
|
||||
|
||||
export interface AvatarEditorFigurePreviewViewProps
|
||||
{
|
@ -1,5 +1,5 @@
|
||||
import { FC, useMemo } from 'react';
|
||||
import { Base, BaseProps } from '../../../common/Base';
|
||||
import { Base, BaseProps } from '../../../common';
|
||||
|
||||
type AvatarIconType = 'male' | 'female' | 'clear' | 'sellable' | string;
|
||||
|
||||
|
@ -1,13 +1,9 @@
|
||||
import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react';
|
||||
import { Column } from '../../../../common/Column';
|
||||
import { Flex } from '../../../../common/Flex';
|
||||
import { Grid } from '../../../../common/Grid';
|
||||
import { CategoryData } from '../../common/CategoryData';
|
||||
import { FigureData } from '../../common/FigureData';
|
||||
import { IAvatarEditorCategoryModel } from '../../common/IAvatarEditorCategoryModel';
|
||||
import { AvatarEditorIcon } from '../AvatarEditorIcon';
|
||||
import { AvatarEditorFigureSetView } from '../figure-set/AvatarEditorFigureSetView';
|
||||
import { AvatarEditorPaletteSetView } from '../palette-set/AvatarEditorPaletteSetView';
|
||||
import { CategoryData, FigureData, IAvatarEditorCategoryModel } from '../../../api';
|
||||
import { Column, Flex, Grid } from '../../../common';
|
||||
import { AvatarEditorIcon } from './AvatarEditorIcon';
|
||||
import { AvatarEditorFigureSetView } from './figure-set/AvatarEditorFigureSetView';
|
||||
import { AvatarEditorPaletteSetView } from './palette-set/AvatarEditorPaletteSetView';
|
||||
export interface AvatarEditorModelViewProps
|
||||
{
|
||||
model: IAvatarEditorCategoryModel;
|
@ -1,8 +1,7 @@
|
||||
import { IAvatarFigureContainer, SaveWardrobeOutfitMessageComposer } from '@nitrots/nitro-renderer';
|
||||
import { Dispatch, FC, SetStateAction, useCallback, useMemo } from 'react';
|
||||
import { GetAvatarRenderManager, GetClubMemberLevel, GetConfiguration, LocalizeText, SendMessageComposer } from '../../../../api';
|
||||
import { AutoGrid, Base, Button, Flex, LayoutAvatarImageView, LayoutCurrencyIcon, LayoutGridItem } from '../../../../common';
|
||||
import { FigureData } from '../../common/FigureData';
|
||||
import { FigureData, GetAvatarRenderManager, GetClubMemberLevel, GetConfiguration, LocalizeText, SendMessageComposer } from '../../../api';
|
||||
import { AutoGrid, Base, Button, Flex, LayoutAvatarImageView, LayoutCurrencyIcon, LayoutGridItem } from '../../../common';
|
||||
|
||||
export interface AvatarEditorWardrobeViewProps
|
||||
{
|
@ -1,7 +1,6 @@
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetConfiguration } from '../../../../api';
|
||||
import { AvatarEditorGridPartItem, GetConfiguration } from '../../../../api';
|
||||
import { LayoutCurrencyIcon, LayoutGridItem, LayoutGridItemProps } from '../../../../common';
|
||||
import { AvatarEditorGridPartItem } from '../../common/AvatarEditorGridPartItem';
|
||||
import { AvatarEditorIcon } from '../AvatarEditorIcon';
|
||||
|
||||
export interface AvatarEditorFigureSetItemViewProps extends LayoutGridItemProps
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { Dispatch, FC, SetStateAction, useCallback } from 'react';
|
||||
import { AutoGrid } from '../../../../common/AutoGrid';
|
||||
import { AvatarEditorGridPartItem } from '../../common/AvatarEditorGridPartItem';
|
||||
import { CategoryData } from '../../common/CategoryData';
|
||||
import { IAvatarEditorCategoryModel } from '../../common/IAvatarEditorCategoryModel';
|
||||
import { AvatarEditorGridPartItem, CategoryData, IAvatarEditorCategoryModel } from '../../../../api';
|
||||
import { AutoGrid } from '../../../../common';
|
||||
import { AvatarEditorFigureSetItemView } from './AvatarEditorFigureSetItemView';
|
||||
|
||||
export interface AvatarEditorFigureSetViewProps
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetConfiguration } from '../../../../api';
|
||||
import { AvatarEditorGridColorItem, GetConfiguration } from '../../../../api';
|
||||
import { LayoutCurrencyIcon, LayoutGridItem, LayoutGridItemProps } from '../../../../common';
|
||||
import { AvatarEditorGridColorItem } from '../../common/AvatarEditorGridColorItem';
|
||||
|
||||
export interface AvatarEditorPaletteSetItemProps extends LayoutGridItemProps
|
||||
{
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { AutoGrid } from '../../../../common/AutoGrid';
|
||||
import { AvatarEditorGridColorItem } from '../../common/AvatarEditorGridColorItem';
|
||||
import { CategoryData } from '../../common/CategoryData';
|
||||
import { IAvatarEditorCategoryModel } from '../../common/IAvatarEditorCategoryModel';
|
||||
import { AvatarEditorGridColorItem, CategoryData, IAvatarEditorCategoryModel } from '../../../../api';
|
||||
import { AutoGrid } from '../../../../common';
|
||||
import { AvatarEditorPaletteSetItem } from './AvatarEditorPaletteSetItemView';
|
||||
|
||||
export interface AvatarEditorPaletteSetViewProps
|
||||
|
@ -1,24 +0,0 @@
|
||||
import { createContext, Dispatch, FC, ProviderProps, SetStateAction, useContext } from 'react';
|
||||
import { CameraPicture } from './common/CameraPicture';
|
||||
|
||||
export interface ICameraWidgetContext
|
||||
{
|
||||
cameraRoll: CameraPicture[],
|
||||
setCameraRoll: Dispatch<SetStateAction<CameraPicture[]>>;
|
||||
selectedPictureIndex: number,
|
||||
setSelectedPictureIndex: Dispatch<SetStateAction<number>>;
|
||||
}
|
||||
|
||||
const CameraWidgetContext = createContext<ICameraWidgetContext>({
|
||||
cameraRoll: null,
|
||||
setCameraRoll: null,
|
||||
selectedPictureIndex: null,
|
||||
setSelectedPictureIndex: null
|
||||
});
|
||||
|
||||
export const CameraWidgetContextProvider: FC<ProviderProps<ICameraWidgetContext>> = props =>
|
||||
{
|
||||
return <CameraWidgetContext.Provider value={ props.value }>{ props.children }</CameraWidgetContext.Provider>
|
||||
}
|
||||
|
||||
export const useCameraWidgetContext = () => useContext(CameraWidgetContext);
|
@ -1,11 +1,9 @@
|
||||
import { ILinkEventTracker, InitCameraMessageEvent, IRoomCameraWidgetEffect, RequestCameraConfigurationComposer, RoomCameraWidgetManagerEvent, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||
import { ILinkEventTracker, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { AddEventLinkTracker, GetRoomCameraWidgetManager, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
|
||||
import { useCameraEvent, useMessageEvent, useRoomSessionManagerEvent } from '../../hooks';
|
||||
import { CameraWidgetContextProvider } from './CameraWidgetContext';
|
||||
import { CameraPicture } from './common/CameraPicture';
|
||||
import { CameraWidgetCaptureView } from './views/capture/CameraWidgetCaptureView';
|
||||
import { CameraWidgetCheckoutView } from './views/checkout/CameraWidgetCheckoutView';
|
||||
import { AddEventLinkTracker, RemoveLinkEventTracker } from '../../api';
|
||||
import { useCamera, useRoomSessionManagerEvent } from '../../hooks';
|
||||
import { CameraWidgetCaptureView } from './views/CameraWidgetCaptureView';
|
||||
import { CameraWidgetCheckoutView } from './views/CameraWidgetCheckoutView';
|
||||
import { CameraWidgetEditorView } from './views/editor/CameraWidgetEditorView';
|
||||
|
||||
const MODE_NONE: number = 0;
|
||||
@ -16,49 +14,10 @@ const MODE_CHECKOUT: number = 3;
|
||||
export const CameraWidgetView: FC<{}> = props =>
|
||||
{
|
||||
const [ mode, setMode ] = useState<number>(MODE_NONE);
|
||||
const [ availableEffects, setAvailableEffects ] = useState<IRoomCameraWidgetEffect[]>([]);
|
||||
const [ cameraRoll, setCameraRoll ] = useState<CameraPicture[]>([]);
|
||||
const [ selectedPictureIndex, setSelectedPictureIndex ] = useState(-1);
|
||||
const [ myLevel, setMyLevel ] = useState(10);
|
||||
const [ base64Url, setSavedPictureUrl ] = useState<string>(null);
|
||||
const [ price, setPrice ] = useState<{ credits: number, duckets: number, publishDucketPrice: number }>(null);
|
||||
const { availableEffects = [], selectedPictureIndex = -1, cameraRoll = [], setCameraRoll = null, myLevel = 0, price = { credits: 0, duckets: 0, publishDucketPrice: 0 }} = useCamera();
|
||||
|
||||
const onRoomCameraWidgetManagerEvent = useCallback((event: RoomCameraWidgetManagerEvent) =>
|
||||
{
|
||||
setAvailableEffects(Array.from(GetRoomCameraWidgetManager().effects.values()))
|
||||
}, []);
|
||||
|
||||
useCameraEvent(RoomCameraWidgetManagerEvent.INITIALIZED, onRoomCameraWidgetManagerEvent);
|
||||
|
||||
const onCameraConfigurationEvent = useCallback((event: InitCameraMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setPrice({ credits: parser.creditPrice, duckets: parser.ducketPrice, publishDucketPrice: parser.publishDucketPrice });
|
||||
}, []);
|
||||
|
||||
useMessageEvent(InitCameraMessageEvent, onCameraConfigurationEvent);
|
||||
|
||||
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
||||
{
|
||||
setMode(MODE_NONE);
|
||||
}, []);
|
||||
|
||||
useRoomSessionManagerEvent(RoomSessionEvent.ENDED, onRoomSessionEvent);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!GetRoomCameraWidgetManager().isLoaded)
|
||||
{
|
||||
GetRoomCameraWidgetManager().init();
|
||||
|
||||
SendMessageComposer(new RequestCameraConfigurationComposer());
|
||||
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const processAction = useCallback((type: string) =>
|
||||
const processAction = (type: string) =>
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
@ -82,7 +41,7 @@ export const CameraWidgetView: FC<{}> = props =>
|
||||
setMode(MODE_CAPTURE);
|
||||
return;
|
||||
}
|
||||
}, [ selectedPictureIndex ]);
|
||||
}
|
||||
|
||||
const checkoutPictureUrl = useCallback((pictureUrl: string) =>
|
||||
{
|
||||
@ -90,7 +49,12 @@ export const CameraWidgetView: FC<{}> = props =>
|
||||
setMode(MODE_CHECKOUT);
|
||||
}, []);
|
||||
|
||||
const linkReceived = useCallback((url: string) =>
|
||||
useRoomSessionManagerEvent<RoomSessionEvent>(RoomSessionEvent.ENDED, event => setMode(MODE_NONE));
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const linkTracker: ILinkEventTracker = {
|
||||
linkReceived: (url: string) =>
|
||||
{
|
||||
const parts = url.split('/');
|
||||
|
||||
@ -112,27 +76,22 @@ export const CameraWidgetView: FC<{}> = props =>
|
||||
});
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const linkTracker: ILinkEventTracker = {
|
||||
linkReceived,
|
||||
},
|
||||
eventUrlPrefix: 'camera/'
|
||||
};
|
||||
|
||||
AddEventLinkTracker(linkTracker);
|
||||
|
||||
return () => RemoveLinkEventTracker(linkTracker);
|
||||
}, [ linkReceived ]);
|
||||
}, []);
|
||||
|
||||
if(mode === MODE_NONE) return null;
|
||||
|
||||
return (
|
||||
<CameraWidgetContextProvider value={ { cameraRoll, setCameraRoll, selectedPictureIndex, setSelectedPictureIndex } }>
|
||||
<>
|
||||
{ (mode === MODE_CAPTURE) && <CameraWidgetCaptureView onClose={ () => processAction('close') } onEdit={ () => processAction('edit') } onDelete={ () => processAction('delete') } /> }
|
||||
{ (mode === MODE_EDITOR) && <CameraWidgetEditorView picture={ cameraRoll[selectedPictureIndex] } myLevel={ myLevel } onClose={ () => processAction('close') } onCancel={ () => processAction('editor_cancel') } onCheckout={ checkoutPictureUrl } availableEffects={ availableEffects } /> }
|
||||
{ (mode === MODE_CHECKOUT) && <CameraWidgetCheckoutView base64Url={ base64Url } onCloseClick={ () => processAction('close') } onCancelClick={ () => processAction('editor_cancel') } price={ price }></CameraWidgetCheckoutView> }
|
||||
</CameraWidgetContextProvider>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { NitroRectangle, TextureUtils } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useRef } from 'react';
|
||||
import { GetRoomEngine, GetRoomSession, LocalizeText, NotificationUtilities, PlaySound, SoundNames } from '../../../../api';
|
||||
import { Column, DraggableWindow, Flex } from '../../../../common';
|
||||
import { useCameraWidgetContext } from '../../CameraWidgetContext';
|
||||
import { CameraPicture } from '../../common/CameraPicture';
|
||||
import { CameraPicture, GetRoomEngine, GetRoomSession, LocalizeText, NotificationUtilities, PlaySound, SoundNames } from '../../../api';
|
||||
import { Column, DraggableWindow, Flex } from '../../../common';
|
||||
import { useCamera } from '../../../hooks';
|
||||
|
||||
export interface CameraWidgetCaptureViewProps
|
||||
{
|
||||
@ -18,7 +17,7 @@ const CAMERA_ROLL_LIMIT: number = 5;
|
||||
export const CameraWidgetCaptureView: FC<CameraWidgetCaptureViewProps> = props =>
|
||||
{
|
||||
const { onClose = null, onEdit = null, onDelete = null } = props;
|
||||
const { cameraRoll = null, setCameraRoll = null, selectedPictureIndex = -1, setSelectedPictureIndex = null } = useCameraWidgetContext();
|
||||
const { cameraRoll = null, setCameraRoll = null, selectedPictureIndex = -1, setSelectedPictureIndex = null } = useCamera();
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
const selectedPicture = ((selectedPictureIndex > -1) ? cameraRoll[selectedPictureIndex] : null);
|
@ -1,8 +1,8 @@
|
||||
import { CameraPublishStatusMessageEvent, CameraPurchaseOKMessageEvent, CameraStorageUrlMessageEvent, PublishPhotoMessageComposer, PurchasePhotoMessageComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { CreateLinkEvent, GetConfiguration, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../../api';
|
||||
import { Button, Column, Flex, LayoutCurrencyIcon, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||
import { useMessageEvent } from '../../../../hooks';
|
||||
import { CreateLinkEvent, GetConfiguration, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../api';
|
||||
import { Button, Column, Flex, LayoutCurrencyIcon, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common';
|
||||
import { useMessageEvent } from '../../../hooks';
|
||||
|
||||
export interface CameraWidgetCheckoutViewProps
|
||||
{
|
@ -2,11 +2,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect, RoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import ReactSlider from 'react-slider';
|
||||
import { GetRoomCameraWidgetManager, LocalizeText } from '../../../../api';
|
||||
import { CameraEditorTabs, CameraPicture, CameraPictureThumbnail, GetRoomCameraWidgetManager, LocalizeText } from '../../../../api';
|
||||
import { Button, ButtonGroup, Column, Flex, Grid, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView, Text } from '../../../../common';
|
||||
import { CameraEditorTabs } from '../../common/CameraEditorTabs';
|
||||
import { CameraPicture } from '../../common/CameraPicture';
|
||||
import { CameraPictureThumbnail } from '../../common/CameraPictureThumbnail';
|
||||
import { CameraWidgetEffectListView } from './effect-list/CameraWidgetEffectListView';
|
||||
|
||||
export interface CameraWidgetEditorViewProps
|
||||
|
@ -2,9 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { IRoomCameraWidgetEffect } from '@nitrots/nitro-renderer';
|
||||
import { FC } from 'react';
|
||||
import { LocalizeText } from '../../../../../api';
|
||||
import { Button } from '../../../../../common/Button';
|
||||
import { LayoutGridItem } from '../../../../../common/layout/LayoutGridItem';
|
||||
import { Text } from '../../../../../common/Text';
|
||||
import { Button, LayoutGridItem, Text } from '../../../../../common';
|
||||
|
||||
export interface CameraWidgetEffectListItemViewProps
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer';
|
||||
import { FC } from 'react';
|
||||
import { CameraPictureThumbnail } from '../../../../../api';
|
||||
import { Grid } from '../../../../../common';
|
||||
import { CameraPictureThumbnail } from '../../../common/CameraPictureThumbnail';
|
||||
import { CameraWidgetEffectListItemView } from './CameraWidgetEffectListItemView';
|
||||
|
||||
export interface CameraWidgetEffectListViewProps
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { FC } from 'react';
|
||||
import { CalendarItemState, GetConfiguration, GetRoomEngine, GetSessionDataManager } from '../../api';
|
||||
import { ICalendarItem } from '../../api/campaign/ICalendarItem';
|
||||
import { CalendarItemState, GetConfiguration, GetRoomEngine, GetSessionDataManager, ICalendarItem } from '../../api';
|
||||
import { Base, Column, Flex, LayoutImage } from '../../common';
|
||||
|
||||
interface CalendarItemViewProps
|
||||
|
@ -1,21 +0,0 @@
|
||||
import { createContext, FC, ProviderProps, useContext } from 'react';
|
||||
import { IChatHistoryState } from './common/IChatHistoryState';
|
||||
import { IRoomHistoryState } from './common/IRoomHistoryState';
|
||||
|
||||
export interface IChatHistoryContext
|
||||
{
|
||||
chatHistoryState: IChatHistoryState;
|
||||
roomHistoryState: IRoomHistoryState;
|
||||
}
|
||||
|
||||
const ChatHistoryContext = createContext<IChatHistoryContext>({
|
||||
chatHistoryState: null,
|
||||
roomHistoryState: null
|
||||
});
|
||||
|
||||
export const ChatHistoryContextProvider: FC<ProviderProps<IChatHistoryContext>> = props =>
|
||||
{
|
||||
return <ChatHistoryContext.Provider value={ props.value }>{ props.children }</ChatHistoryContext.Provider>
|
||||
}
|
||||
|
||||
export const useChatHistoryContext = () => useContext(ChatHistoryContext);
|
@ -1,112 +0,0 @@
|
||||
import { GetGuestRoomResultEvent, RoomSessionChatEvent, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetRoomSession } from '../../api';
|
||||
import { useMessageEvent, useRoomSessionManagerEvent } from '../../hooks';
|
||||
import { useChatHistoryContext } from './ChatHistoryContext';
|
||||
import { ChatEntryType } from './common/ChatEntryType';
|
||||
import { IChatEntry } from './common/IChatEntry';
|
||||
import { IRoomHistoryEntry } from './common/IRoomHistoryEntry';
|
||||
import { currentDate } from './common/Utilities';
|
||||
|
||||
const CHAT_HISTORY_MAX = 1000;
|
||||
const ROOM_HISTORY_MAX = 10;
|
||||
|
||||
export const ChatHistoryMessageHandler: FC<{}> = props =>
|
||||
{
|
||||
const { chatHistoryState = null, roomHistoryState = null } = useChatHistoryContext();
|
||||
|
||||
const [ needsRoomInsert, setNeedsRoomInsert ] = useState(false);
|
||||
|
||||
const addChatEntry = useCallback((entry: IChatEntry) =>
|
||||
{
|
||||
entry.id = chatHistoryState.chats.length;
|
||||
|
||||
chatHistoryState.chats.push(entry);
|
||||
|
||||
//check for overflow
|
||||
if(chatHistoryState.chats.length > CHAT_HISTORY_MAX)
|
||||
{
|
||||
chatHistoryState.chats.shift();
|
||||
}
|
||||
chatHistoryState.notify();
|
||||
|
||||
//dispatchUiEvent(new ChatHistoryEvent(ChatHistoryEvent.CHAT_HISTORY_CHANGED));
|
||||
|
||||
}, [ chatHistoryState ]);
|
||||
|
||||
const addRoomHistoryEntry = useCallback((entry: IRoomHistoryEntry) =>
|
||||
{
|
||||
roomHistoryState.roomHistory.push(entry);
|
||||
|
||||
// check for overflow
|
||||
if(roomHistoryState.roomHistory.length > ROOM_HISTORY_MAX)
|
||||
{
|
||||
roomHistoryState.roomHistory.shift();
|
||||
}
|
||||
|
||||
roomHistoryState.notify();
|
||||
}, [ roomHistoryState ]);
|
||||
|
||||
const onChatEvent = useCallback((event: RoomSessionChatEvent) =>
|
||||
{
|
||||
const roomSession = GetRoomSession();
|
||||
|
||||
if(!roomSession) return;
|
||||
|
||||
const userData = roomSession.userDataManager.getUserDataByIndex(event.objectId);
|
||||
|
||||
if(!userData) return;
|
||||
|
||||
const timeString = currentDate();
|
||||
|
||||
const entry: IChatEntry = { id: -1, entityId: userData.webID, name: userData.name, look: userData.figure, entityType: userData.type, message: event.message, timestamp: timeString, type: ChatEntryType.TYPE_CHAT, roomId: roomSession.roomId };
|
||||
|
||||
addChatEntry(entry);
|
||||
}, [ addChatEntry ]);
|
||||
|
||||
useRoomSessionManagerEvent(RoomSessionChatEvent.CHAT_EVENT, onChatEvent);
|
||||
|
||||
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomSessionEvent.STARTED:
|
||||
setNeedsRoomInsert(true);
|
||||
break;
|
||||
case RoomSessionEvent.ENDED:
|
||||
//dispatchUiEvent(new ChatHistoryEvent(ChatHistoryEvent.HIDE_CHAT_HISTORY));
|
||||
break;
|
||||
}
|
||||
}, []);
|
||||
|
||||
useRoomSessionManagerEvent(RoomSessionEvent.ENDED, onRoomSessionEvent);
|
||||
useRoomSessionManagerEvent(RoomSessionEvent.STARTED, onRoomSessionEvent);
|
||||
|
||||
const onGetGuestRoomResultEvent = useCallback((event: GetGuestRoomResultEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
if(!parser) return;
|
||||
|
||||
const session = GetRoomSession();
|
||||
|
||||
if(!session || (session.roomId !== parser.data.roomId)) return;
|
||||
|
||||
if(needsRoomInsert)
|
||||
{
|
||||
const chatEntry: IChatEntry = { id: -1, entityId: parser.data.roomId, name: parser.data.roomName, timestamp: currentDate(), type: ChatEntryType.TYPE_ROOM_INFO, roomId: parser.data.roomId };
|
||||
|
||||
addChatEntry(chatEntry);
|
||||
|
||||
const roomEntry: IRoomHistoryEntry = { id: parser.data.roomId, name: parser.data.roomName };
|
||||
|
||||
addRoomHistoryEntry(roomEntry);
|
||||
|
||||
setNeedsRoomInsert(false);
|
||||
}
|
||||
}, [ addChatEntry, addRoomHistoryEntry, needsRoomInsert ]);
|
||||
|
||||
useMessageEvent(GetGuestRoomResultEvent, onGetGuestRoomResultEvent);
|
||||
|
||||
return null;
|
||||
}
|
@ -1,29 +1,21 @@
|
||||
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { FC, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps, ListRowRenderer, Size } from 'react-virtualized';
|
||||
import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../api';
|
||||
import { AddEventLinkTracker, ChatEntryType, LocalizeText, RemoveLinkEventTracker } from '../../api';
|
||||
import { Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common';
|
||||
import { ChatHistoryContextProvider } from './ChatHistoryContext';
|
||||
import { ChatHistoryMessageHandler } from './ChatHistoryMessageHandler';
|
||||
import { ChatEntryType } from './common/ChatEntryType';
|
||||
import { ChatHistoryState } from './common/ChatHistoryState';
|
||||
import { SetChatHistory } from './common/GetChatHistory';
|
||||
import { RoomHistoryState } from './common/RoomHistoryState';
|
||||
import { useChatHistory } from '../../hooks';
|
||||
|
||||
export const ChatHistoryView: FC<{}> = props =>
|
||||
{
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const [ chatHistoryUpdateId, setChatHistoryUpdateId ] = useState(-1);
|
||||
const [ roomHistoryUpdateId, setRoomHistoryUpdateId ] = useState(-1);
|
||||
const [ chatHistoryState, setChatHistoryState ] = useState(new ChatHistoryState());
|
||||
const [ roomHistoryState, setRoomHistoryState ] = useState(new RoomHistoryState());
|
||||
const { chatHistory = [] } = useChatHistory();
|
||||
const elementRef = useRef<List>(null);
|
||||
|
||||
const cache = useMemo(() => new CellMeasurerCache({ defaultHeight: 25, fixedWidth: true }), []);
|
||||
|
||||
const RowRenderer: ListRowRenderer = (props: ListRowProps) =>
|
||||
{
|
||||
const item = chatHistoryState.chats[props.index];
|
||||
const item = chatHistory[props.index];
|
||||
|
||||
const isDark = (props.index % 2 === 0);
|
||||
|
||||
@ -48,7 +40,10 @@ export const ChatHistoryView: FC<{}> = props =>
|
||||
|
||||
const onResize = (info: Size) => cache.clearAll();
|
||||
|
||||
const linkReceived = useCallback((url: string) =>
|
||||
useEffect(() =>
|
||||
{
|
||||
const linkTracker: ILinkEventTracker = {
|
||||
linkReceived: (url: string) =>
|
||||
{
|
||||
const parts = url.split('/');
|
||||
|
||||
@ -66,38 +61,13 @@ export const ChatHistoryView: FC<{}> = props =>
|
||||
setIsVisible(prevValue => !prevValue);
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const linkTracker: ILinkEventTracker = {
|
||||
linkReceived,
|
||||
},
|
||||
eventUrlPrefix: 'chat-history/'
|
||||
};
|
||||
|
||||
AddEventLinkTracker(linkTracker);
|
||||
|
||||
return () => RemoveLinkEventTracker(linkTracker);
|
||||
}, [ linkReceived ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const chatState = new ChatHistoryState();
|
||||
const roomState = new RoomHistoryState();
|
||||
|
||||
SetChatHistory(chatState);
|
||||
|
||||
chatState.notifier = () => setChatHistoryUpdateId(prevValue => (prevValue + 1));
|
||||
roomState.notifier = () => setRoomHistoryUpdateId(prevValue => (prevValue + 1));
|
||||
|
||||
setChatHistoryState(chatState);
|
||||
setRoomHistoryState(roomState);
|
||||
|
||||
return () =>
|
||||
{
|
||||
chatState.notifier = null;
|
||||
roomState.notifier = null;
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
@ -105,10 +75,9 @@ export const ChatHistoryView: FC<{}> = props =>
|
||||
if(elementRef && elementRef.current && isVisible) elementRef.current.scrollToRow(-1);
|
||||
}, [ isVisible ]);
|
||||
|
||||
if(!isVisible) return null;
|
||||
|
||||
return (
|
||||
<ChatHistoryContextProvider value={ { chatHistoryState, roomHistoryState } }>
|
||||
<ChatHistoryMessageHandler />
|
||||
{ isVisible &&
|
||||
<NitroCardView uniqueKey="chat-history" className="nitro-chat-history" theme="primary-slim">
|
||||
<NitroCardHeaderView headerText={ LocalizeText('room.chathistory.button.text') } onCloseClick={ event => setIsVisible(false) }/>
|
||||
<NitroCardContentView>
|
||||
@ -120,7 +89,7 @@ export const ChatHistoryView: FC<{}> = props =>
|
||||
ref={ elementRef }
|
||||
width={ width }
|
||||
height={ height }
|
||||
rowCount={ chatHistoryState.chats.length }
|
||||
rowCount={ chatHistory.length }
|
||||
rowHeight={ cache.rowHeight }
|
||||
className={ 'chat-history-list' }
|
||||
rowRenderer={ RowRenderer }
|
||||
@ -129,7 +98,6 @@ export const ChatHistoryView: FC<{}> = props =>
|
||||
} }
|
||||
</AutoSizer>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView> }
|
||||
</ChatHistoryContextProvider>
|
||||
</NitroCardView>
|
||||
);
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
import { IChatEntry } from './IChatEntry';
|
||||
import { IChatHistoryState } from './IChatHistoryState';
|
||||
|
||||
export class ChatHistoryState implements IChatHistoryState
|
||||
{
|
||||
private _chats: IChatEntry[];
|
||||
private _notifier: () => void;
|
||||
|
||||
constructor()
|
||||
{
|
||||
this._chats = [];
|
||||
}
|
||||
|
||||
public notify(): void
|
||||
{
|
||||
if(this._notifier) this._notifier();
|
||||
}
|
||||
|
||||
public get chats(): IChatEntry[]
|
||||
{
|
||||
return this._chats;
|
||||
}
|
||||
|
||||
public get notifier(): () => void
|
||||
{
|
||||
return this._notifier;
|
||||
}
|
||||
|
||||
public set notifier(notifier: () => void)
|
||||
{
|
||||
this._notifier = notifier;
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { IChatHistoryState } from './IChatHistoryState';
|
||||
|
||||
let GLOBAL_CHATS: IChatHistoryState = null;
|
||||
|
||||
export const SetChatHistory = (chatHistory: IChatHistoryState) => (GLOBAL_CHATS = chatHistory);
|
||||
|
||||
export const GetChatHistory = () => GLOBAL_CHATS;
|
@ -1,8 +0,0 @@
|
||||
import { IChatEntry } from './IChatEntry';
|
||||
|
||||
export interface IChatHistoryState
|
||||
{
|
||||
chats: IChatEntry[];
|
||||
notifier: () => void
|
||||
notify(): void;
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
export interface IRoomHistoryEntry {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import { IRoomHistoryEntry } from './IRoomHistoryEntry';
|
||||
|
||||
export interface IRoomHistoryState
|
||||
{
|
||||
roomHistory: IRoomHistoryEntry[];
|
||||
notifier: () => void;
|
||||
notify: () => void;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
import { IRoomHistoryEntry } from './IRoomHistoryEntry';
|
||||
import { IRoomHistoryState } from './IRoomHistoryState';
|
||||
|
||||
export class RoomHistoryState implements IRoomHistoryState
|
||||
{
|
||||
private _roomHistory: IRoomHistoryEntry[];
|
||||
private _notifier: () => void;
|
||||
|
||||
constructor()
|
||||
{
|
||||
this._roomHistory = [];
|
||||
}
|
||||
|
||||
public get roomHistory(): IRoomHistoryEntry[]
|
||||
{
|
||||
return this._roomHistory;
|
||||
}
|
||||
|
||||
public get notifier(): () => void
|
||||
{
|
||||
return this._notifier;
|
||||
}
|
||||
|
||||
public set notifier(notifier: () => void)
|
||||
{
|
||||
this._notifier = notifier;
|
||||
}
|
||||
|
||||
notify(): void
|
||||
{
|
||||
if(this._notifier) this._notifier();
|
||||
}
|
||||
}
|
@ -1,18 +1,18 @@
|
||||
import { FC, useMemo } from 'react';
|
||||
import { GetGroupChatData, GetSessionDataManager, GroupType, LocalizeText, MessengerThread, MessengerThreadChat, MessengerThreadChatGroup } from '../../../../../api';
|
||||
import { GetGroupChatData, GetSessionDataManager, LocalizeText, MessengerGroupType, MessengerThread, MessengerThreadChat, MessengerThreadChatGroup } from '../../../../../api';
|
||||
import { Base, Flex, LayoutAvatarImageView } from '../../../../../common';
|
||||
|
||||
export const FriendsMessengerThreadGroup: FC<{ thread: MessengerThread, group: MessengerThreadChatGroup }> = props =>
|
||||
{
|
||||
const { thread = null, group = null } = props;
|
||||
|
||||
const groupChatData = useMemo(() => ((group.type === GroupType.GROUP_CHAT) && GetGroupChatData(group.chats[0].extraData)), [ group ]);
|
||||
const groupChatData = useMemo(() => ((group.type === MessengerGroupType.GROUP_CHAT) && GetGroupChatData(group.chats[0].extraData)), [ group ]);
|
||||
|
||||
const isOwnChat = useMemo(() =>
|
||||
{
|
||||
if(!thread || !group) return false;
|
||||
|
||||
if((group.type === GroupType.PRIVATE_CHAT) && (group.userId === GetSessionDataManager().userId)) return true;
|
||||
if((group.type === MessengerGroupType.PRIVATE_CHAT) && (group.userId === GetSessionDataManager().userId)) return true;
|
||||
|
||||
if(groupChatData && group.chats.length && (groupChatData.userId === GetSessionDataManager().userId)) return true;
|
||||
|
||||
@ -51,7 +51,7 @@ export const FriendsMessengerThreadGroup: FC<{ thread: MessengerThread, group: M
|
||||
return (
|
||||
<Flex fullWidth justifyContent={ isOwnChat ? 'end' : 'start' } gap={ 2 }>
|
||||
<Base shrink className="message-avatar">
|
||||
{ ((group.type === GroupType.PRIVATE_CHAT) && !isOwnChat) &&
|
||||
{ ((group.type === MessengerGroupType.PRIVATE_CHAT) && !isOwnChat) &&
|
||||
<LayoutAvatarImageView figure={ thread.participant.figure } direction={ 2 } /> }
|
||||
{ (groupChatData && !isOwnChat) &&
|
||||
<LayoutAvatarImageView figure={ groupChatData.figure } direction={ 2 } /> }
|
||||
|
@ -1,20 +0,0 @@
|
||||
import { createContext, Dispatch, FC, ProviderProps, SetStateAction, useContext } from 'react';
|
||||
import { IGroupCustomize } from './common/IGroupCustomize';
|
||||
|
||||
interface IGroupsContext
|
||||
{
|
||||
groupCustomize: IGroupCustomize;
|
||||
setGroupCustomize: Dispatch<SetStateAction<IGroupCustomize>>;
|
||||
}
|
||||
|
||||
const GroupsContext = createContext<IGroupsContext>({
|
||||
groupCustomize: null,
|
||||
setGroupCustomize: null
|
||||
});
|
||||
|
||||
export const GroupsContextProvider: FC<ProviderProps<IGroupsContext>> = props =>
|
||||
{
|
||||
return <GroupsContext.Provider value={ props.value }>{ props.children }</GroupsContext.Provider>
|
||||
}
|
||||
|
||||
export const useGroupsContext = () => useContext(GroupsContext);
|
@ -1,10 +1,7 @@
|
||||
import { GroupBadgePartsComposer, GroupBadgePartsEvent, GroupPurchasedEvent, GroupSettingsComposer, ILinkEventTracker } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GroupPurchasedEvent, GroupSettingsComposer, ILinkEventTracker } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { AddEventLinkTracker, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api';
|
||||
import { useMessageEvent } from '../../hooks';
|
||||
import { CompareId } from './common/CompareId';
|
||||
import { IGroupCustomize } from './common/IGroupCustomize';
|
||||
import { GroupsContextProvider } from './GroupsContext';
|
||||
import { GroupCreatorView } from './views/GroupCreatorView';
|
||||
import { GroupInformationStandaloneView } from './views/GroupInformationStandaloneView';
|
||||
import { GroupManagerView } from './views/GroupManagerView';
|
||||
@ -13,48 +10,19 @@ import { GroupMembersView } from './views/GroupMembersView';
|
||||
export const GroupsView: FC<{}> = props =>
|
||||
{
|
||||
const [ isCreatorVisible, setCreatorVisible ] = useState<boolean>(false);
|
||||
const [ groupCustomize, setGroupCustomize ] = useState<IGroupCustomize>(null);
|
||||
|
||||
const onGroupPurchasedEvent = useCallback((event: GroupPurchasedEvent) =>
|
||||
useMessageEvent<GroupPurchasedEvent>(GroupPurchasedEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setCreatorVisible(false);
|
||||
TryVisitRoom(parser.roomId);
|
||||
}, []);
|
||||
});
|
||||
|
||||
useMessageEvent(GroupPurchasedEvent, onGroupPurchasedEvent);
|
||||
|
||||
const onGroupBadgePartsEvent = useCallback((event: GroupBadgePartsEvent) =>
|
||||
useEffect(() =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
const customize: IGroupCustomize = {
|
||||
badgeBases: [],
|
||||
badgeSymbols: [],
|
||||
badgePartColors: [],
|
||||
groupColorsA: [],
|
||||
groupColorsB: []
|
||||
};
|
||||
|
||||
parser.bases.forEach((images, id) => customize.badgeBases.push({ id, images }));
|
||||
parser.symbols.forEach((images, id) => customize.badgeSymbols.push({ id, images }));
|
||||
parser.partColors.forEach((color, id) => customize.badgePartColors.push({ id, color }));
|
||||
parser.colorsA.forEach((color, id) => customize.groupColorsA.push({ id, color }));
|
||||
parser.colorsB.forEach((color, id) => customize.groupColorsB.push({ id, color }));
|
||||
|
||||
customize.badgeBases.sort(CompareId);
|
||||
customize.badgeSymbols.sort(CompareId);
|
||||
customize.badgePartColors.sort(CompareId);
|
||||
customize.groupColorsA.sort(CompareId);
|
||||
customize.groupColorsB.sort(CompareId);
|
||||
|
||||
setGroupCustomize(customize);
|
||||
}, [ setGroupCustomize ]);
|
||||
|
||||
useMessageEvent(GroupBadgePartsEvent, onGroupBadgePartsEvent);
|
||||
|
||||
const linkReceived = useCallback((url: string) =>
|
||||
const linkTracker: ILinkEventTracker = {
|
||||
linkReceived: (url: string) =>
|
||||
{
|
||||
const parts = url.split('/');
|
||||
|
||||
@ -72,33 +40,23 @@ export const GroupsView: FC<{}> = props =>
|
||||
SendMessageComposer(new GroupSettingsComposer(Number(parts[2])));
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const linkTracker: ILinkEventTracker = {
|
||||
linkReceived,
|
||||
},
|
||||
eventUrlPrefix: 'groups/'
|
||||
};
|
||||
|
||||
AddEventLinkTracker(linkTracker);
|
||||
|
||||
return () => RemoveLinkEventTracker(linkTracker);
|
||||
}, [ linkReceived ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
SendMessageComposer(new GroupBadgePartsComposer());
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<GroupsContextProvider value={ { groupCustomize, setGroupCustomize } }>
|
||||
<>
|
||||
{ isCreatorVisible &&
|
||||
<GroupCreatorView onClose={ () => setCreatorVisible(false) } /> }
|
||||
{ !isCreatorVisible &&
|
||||
<GroupManagerView /> }
|
||||
<GroupMembersView />
|
||||
<GroupInformationStandaloneView />
|
||||
</GroupsContextProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,8 +0,0 @@
|
||||
export const CompareId = (a, b) =>
|
||||
{
|
||||
if(a.id < b.id) return -1;
|
||||
|
||||
if(a.id > b.id) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { Dispatch, FC, SetStateAction, useState } from 'react';
|
||||
import { GroupBadgePart } from '../../../api';
|
||||
import { Base, Column, Flex, Grid, LayoutBadgeImageView } from '../../../common';
|
||||
import { GroupBadgePart } from '../common/GroupBadgePart';
|
||||
import { useGroupsContext } from '../GroupsContext';
|
||||
import { useGroup } from '../../../hooks';
|
||||
|
||||
interface GroupBadgeCreatorViewProps
|
||||
{
|
||||
@ -16,7 +16,7 @@ export const GroupBadgeCreatorView: FC<GroupBadgeCreatorViewProps> = props =>
|
||||
{
|
||||
const { badgeParts = [], setBadgeParts = null } = props;
|
||||
const [ selectedIndex, setSelectedIndex ] = useState<number>(-1);
|
||||
const { groupCustomize = null } = useGroupsContext();
|
||||
const { groupCustomize = null } = useGroup();
|
||||
|
||||
const setPartProperty = (partIndex: number, property: string, value: number) =>
|
||||
{
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { GroupBuyComposer, GroupBuyDataComposer, GroupBuyDataEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { HasHabboClub, LocalizeText, SendMessageComposer } from '../../../api';
|
||||
import { HasHabboClub, IGroupData, LocalizeText, SendMessageComposer } from '../../../api';
|
||||
import { Base, Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common';
|
||||
import { useMessageEvent } from '../../../hooks';
|
||||
import { IGroupData } from '../common/IGroupData';
|
||||
import { GroupTabBadgeView } from './tabs/GroupTabBadgeView';
|
||||
import { GroupTabColorsView } from './tabs/GroupTabColorsView';
|
||||
import { GroupTabCreatorConfirmationView } from './tabs/GroupTabCreatorConfirmationView';
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { GroupInformationParser, GroupRemoveMemberComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { CatalogPageName, CreateLinkEvent, GetGroupManager, GetGroupMembers, GetSessionDataManager, LocalizeText, NotificationUtilities, SendMessageComposer, TryJoinGroup, TryVisitRoom } from '../../../api';
|
||||
import { CatalogPageName, CreateLinkEvent, GetGroupManager, GetGroupMembers, GetSessionDataManager, GroupMembershipType, GroupType, LocalizeText, NotificationUtilities, SendMessageComposer, TryJoinGroup, TryVisitRoom } from '../../../api';
|
||||
import { Button, Column, Flex, Grid, GridProps, LayoutBadgeImageView, Text } from '../../../common';
|
||||
import { GroupMembershipType } from '../common/GroupMembershipType';
|
||||
import { GroupType } from '../common/GroupType';
|
||||
|
||||
const STATES: string[] = [ 'regular', 'exclusive', 'private' ];
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { GroupBadgePart, GroupInformationEvent, GroupSettingsEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText } from '../../../api';
|
||||
import { IGroupData, LocalizeText } from '../../../api';
|
||||
import { Base, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView, Text } from '../../../common';
|
||||
import { useMessageEvent } from '../../../hooks';
|
||||
import { IGroupData } from '../common/IGroupData';
|
||||
import { GroupTabBadgeView } from './tabs/GroupTabBadgeView';
|
||||
import { GroupTabColorsView } from './tabs/GroupTabColorsView';
|
||||
import { GroupTabIdentityView } from './tabs/GroupTabIdentityView';
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { DesktopViewEvent, GetGuestRoomResultEvent, GroupInformationComposer, GroupInformationEvent, GroupInformationParser, GroupRemoveMemberComposer, HabboGroupDeactivatedMessageEvent, RoomEntryInfoMessageEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetGroupInformation, GetGroupManager, GetSessionDataManager, LocalizeText, NotificationUtilities, SendMessageComposer, TryJoinGroup } from '../../../api';
|
||||
import { GetGroupInformation, GetGroupManager, GetSessionDataManager, GroupMembershipType, GroupType, LocalizeText, NotificationUtilities, SendMessageComposer, TryJoinGroup } from '../../../api';
|
||||
import { Base, Button, Column, Flex, LayoutBadgeImageView, Text } from '../../../common';
|
||||
import { useMessageEvent } from '../../../hooks';
|
||||
import { GroupMembershipType } from '../common/GroupMembershipType';
|
||||
import { GroupType } from '../common/GroupType';
|
||||
|
||||
export const GroupRoomInformationView: FC<{}> = props =>
|
||||
{
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { GroupSaveBadgeComposer } from '@nitrots/nitro-renderer';
|
||||
import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react';
|
||||
import { SendMessageComposer } from '../../../../api';
|
||||
import { GroupBadgePart, IGroupData, SendMessageComposer } from '../../../../api';
|
||||
import { Column, Flex, Grid, LayoutBadgeImageView } from '../../../../common';
|
||||
import { GroupBadgePart } from '../../common/GroupBadgePart';
|
||||
import { IGroupData } from '../../common/IGroupData';
|
||||
import { useGroupsContext } from '../../GroupsContext';
|
||||
import { useGroup } from '../../../../hooks';
|
||||
import { GroupBadgeCreatorView } from '../GroupBadgeCreatorView';
|
||||
|
||||
interface GroupTabBadgeViewProps
|
||||
@ -19,7 +17,7 @@ export const GroupTabBadgeView: FC<GroupTabBadgeViewProps> = props =>
|
||||
{
|
||||
const { groupData = null, setGroupData = null, setCloseAction = null, skipDefault = null } = props;
|
||||
const [ badgeParts, setBadgeParts ] = useState<GroupBadgePart[]>(null);
|
||||
const { groupCustomize = null } = useGroupsContext();
|
||||
const { groupCustomize = null } = useGroup();
|
||||
|
||||
const getModifiedBadgeCode = () =>
|
||||
{
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { GroupSaveColorsComposer } from '@nitrots/nitro-renderer';
|
||||
import classNames from 'classnames';
|
||||
import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react';
|
||||
import { LocalizeText, SendMessageComposer } from '../../../../api';
|
||||
import { IGroupData, LocalizeText, SendMessageComposer } from '../../../../api';
|
||||
import { AutoGrid, Base, Column, Flex, Grid, Text } from '../../../../common';
|
||||
import { IGroupData } from '../../common/IGroupData';
|
||||
import { useGroupsContext } from '../../GroupsContext';
|
||||
import { useGroup } from '../../../../hooks';
|
||||
|
||||
interface GroupTabColorsViewProps
|
||||
{
|
||||
@ -17,7 +16,7 @@ export const GroupTabColorsView: FC<GroupTabColorsViewProps> = props =>
|
||||
{
|
||||
const { groupData = null, setGroupData = null, setCloseAction = null } = props;
|
||||
const [ colors, setColors ] = useState<number[]>(null);
|
||||
const { groupCustomize = null } = useGroupsContext();
|
||||
const { groupCustomize = null } = useGroup();
|
||||
|
||||
const getGroupColor = (colorIndex: number) =>
|
||||
{
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Dispatch, FC, SetStateAction } from 'react';
|
||||
import { LocalizeText } from '../../../../api';
|
||||
import { IGroupData, LocalizeText } from '../../../../api';
|
||||
import { Base, Column, Flex, Grid, LayoutBadgeImageView, Text } from '../../../../common';
|
||||
import { IGroupData } from '../../common/IGroupData';
|
||||
import { useGroupsContext } from '../../GroupsContext';
|
||||
import { useGroup } from '../../../../hooks';
|
||||
|
||||
interface GroupTabCreatorConfirmationViewProps
|
||||
{
|
||||
@ -14,7 +13,7 @@ interface GroupTabCreatorConfirmationViewProps
|
||||
export const GroupTabCreatorConfirmationView: FC<GroupTabCreatorConfirmationViewProps> = props =>
|
||||
{
|
||||
const { groupData = null, setGroupData = null, purchaseCost = 0 } = props;
|
||||
const { groupCustomize = null } = useGroupsContext();
|
||||
const { groupCustomize = null } = useGroup();
|
||||
|
||||
const getCompleteBadgeCode = () =>
|
||||
{
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { GroupDeleteComposer, GroupSaveInformationComposer } from '@nitrots/nitro-renderer';
|
||||
import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react';
|
||||
import { CreateLinkEvent, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../api';
|
||||
import { CreateLinkEvent, IGroupData, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../api';
|
||||
import { Base, Button, Column, Flex, Text } from '../../../../common';
|
||||
import { IGroupData } from '../../common/IGroupData';
|
||||
|
||||
interface GroupTabIdentityViewProps
|
||||
{
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { GroupSavePreferencesComposer } from '@nitrots/nitro-renderer';
|
||||
import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react';
|
||||
import { SendMessageComposer } from '../../../../api';
|
||||
import { LocalizeText } from '../../../../api/utils/LocalizeText';
|
||||
import { IGroupData, LocalizeText, SendMessageComposer } from '../../../../api';
|
||||
import { Column, Flex, HorizontalRule, Text } from '../../../../common';
|
||||
import { IGroupData } from '../../common/IGroupData';
|
||||
|
||||
const STATES: string[] = [ 'regular', 'exclusive', 'private' ];
|
||||
|
||||
|
@ -1,12 +1,9 @@
|
||||
import { GuideOnDutyStatusMessageEvent, GuideSessionAttachedMessageEvent, GuideSessionDetachedMessageEvent, GuideSessionEndedMessageEvent, GuideSessionInvitedToGuideRoomMessageEvent, GuideSessionMessageMessageEvent, GuideSessionOnDutyUpdateMessageComposer, GuideSessionPartnerIsTypingMessageEvent, GuideSessionStartedMessageEvent, ILinkEventTracker, PerkAllowancesMessageEvent, PerkEnum } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { AddEventLinkTracker, DispatchUiEvent, GetConfiguration, GetSessionDataManager, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
|
||||
import { AddEventLinkTracker, DispatchUiEvent, GetConfiguration, GetSessionDataManager, GuideSessionState, GuideToolMessage, GuideToolMessageGroup, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common';
|
||||
import { GuideToolEvent, NotificationAlertEvent } from '../../events';
|
||||
import { useMessageEvent, useUiEvent } from '../../hooks';
|
||||
import { GuideSessionState } from './common/GuideSessionState';
|
||||
import { GuideToolMessage } from './common/GuideToolMessage';
|
||||
import { GuideToolMessageGroup } from './common/GuideToolMessageGroup';
|
||||
import { GuideToolAcceptView } from './views/GuideToolAcceptView';
|
||||
import { GuideToolMenuView } from './views/GuideToolMenuView';
|
||||
import { GuideToolOngoingView } from './views/GuideToolOngoingView';
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { GuideSessionGetRequesterRoomMessageComposer, GuideSessionInviteRequesterMessageComposer, GuideSessionMessageMessageComposer, GuideSessionRequesterRoomMessageEvent, GuideSessionResolvedMessageComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, KeyboardEvent, useCallback, useState } from 'react';
|
||||
import { GetSessionDataManager, LocalizeText, SendMessageComposer, TryVisitRoom } from '../../../api';
|
||||
import { GetSessionDataManager, GuideToolMessageGroup, LocalizeText, SendMessageComposer, TryVisitRoom } from '../../../api';
|
||||
import { Base, Button, ButtonGroup, Column, Flex, LayoutAvatarImageView, Text } from '../../../common';
|
||||
import { useMessageEvent } from '../../../hooks';
|
||||
import { GuideToolMessageGroup } from '../common/GuideToolMessageGroup';
|
||||
|
||||
interface GuideToolOngoingViewProps
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createContext, Dispatch, FC, ProviderProps, SetStateAction, useContext } from 'react';
|
||||
import { IHelpReportState } from './common/IHelpReportState';
|
||||
import { IHelpReportState } from '../../api';
|
||||
|
||||
interface IHelpContext
|
||||
{
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { CallForHelpResultMessageEvent, GetPendingCallsForHelpMessageComposer, IssueCloseNotificationMessageEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer } from '../../api';
|
||||
import { CallForHelpResult, GetCloseReasonKey, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer } from '../../api';
|
||||
import { useMessageEvent } from '../../hooks';
|
||||
import { CallForHelpResult } from './common/CallForHelpResult';
|
||||
import { GetCloseReasonKey } from './common/GetCloseReasonKey';
|
||||
|
||||
export const HelpMessageHandler: FC<{}> = props =>
|
||||
{
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../api';
|
||||
import { AddEventLinkTracker, IHelpReportState, LocalizeText, RemoveLinkEventTracker } from '../../api';
|
||||
import { Base, Column, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common';
|
||||
import { HelpReportUserEvent } from '../../events/help/HelpReportUserEvent';
|
||||
import { HelpReportUserEvent } from '../../events';
|
||||
import { useUiEvent } from '../../hooks';
|
||||
import { IHelpReportState } from './common/IHelpReportState';
|
||||
import { HelpContextProvider } from './HelpContext';
|
||||
import { HelpMessageHandler } from './HelpMessageHandler';
|
||||
import { DescribeReportView } from './views/DescribeReportView';
|
||||
|
@ -1,22 +1,21 @@
|
||||
import { RoomObjectType } from '@nitrots/nitro-renderer';
|
||||
import { FC, useMemo, useState } from 'react';
|
||||
import { LocalizeText } from '../../../api';
|
||||
import { ChatEntryType, IChatEntry, LocalizeText } from '../../../api';
|
||||
import { AutoGrid, Button, Column, Flex, LayoutGridItem, Text } from '../../../common';
|
||||
import { ChatEntryType } from '../../chat-history/common/ChatEntryType';
|
||||
import { GetChatHistory } from '../../chat-history/common/GetChatHistory';
|
||||
import { IChatEntry } from '../../chat-history/common/IChatEntry';
|
||||
import { useChatHistory } from '../../../hooks';
|
||||
import { useHelpContext } from '../HelpContext';
|
||||
|
||||
export const SelectReportedChatsView: FC<{}> = props =>
|
||||
{
|
||||
const [ selectedChats, setSelectedChats ] = useState<Map<number, IChatEntry>>(new Map());
|
||||
const { chatHistory = [] } = useChatHistory();
|
||||
const { helpReportState = null, setHelpReportState = null } = useHelpContext();
|
||||
const { reportedUserId = -1 } = helpReportState;
|
||||
|
||||
const userChats = useMemo(() =>
|
||||
{
|
||||
return GetChatHistory().chats.filter(chat => (chat.type === ChatEntryType.TYPE_CHAT) && (chat.entityId === reportedUserId) && (chat.entityType === RoomObjectType.USER));
|
||||
}, [ reportedUserId ]);
|
||||
return chatHistory.filter(chat => (chat.type === ChatEntryType.TYPE_CHAT) && (chat.entityId === reportedUserId) && (chat.entityType === RoomObjectType.USER));
|
||||
}, [ chatHistory, reportedUserId ]);
|
||||
|
||||
const selectChat = (chatEntry: IChatEntry) =>
|
||||
{
|
||||
|
@ -1,22 +1,21 @@
|
||||
import { RoomObjectType } from '@nitrots/nitro-renderer';
|
||||
import { FC, useMemo, useState } from 'react';
|
||||
import { GetSessionDataManager, LocalizeText } from '../../../api';
|
||||
import { ChatEntryType, GetSessionDataManager, IReportedUser, LocalizeText } from '../../../api';
|
||||
import { AutoGrid, Button, Column, Flex, LayoutGridItem, Text } from '../../../common';
|
||||
import { ChatEntryType } from '../../chat-history/common/ChatEntryType';
|
||||
import { GetChatHistory } from '../../chat-history/common/GetChatHistory';
|
||||
import { IReportedUser } from '../common/IReportedUser';
|
||||
import { useChatHistory } from '../../../hooks';
|
||||
import { useHelpContext } from '../HelpContext';
|
||||
|
||||
export const SelectReportedUserView: FC<{}> = props =>
|
||||
{
|
||||
const [ selectedUserId, setSelectedUserId ] = useState(-1);
|
||||
const { chatHistory = [] } = useChatHistory();
|
||||
const { helpReportState = null, setHelpReportState = null } = useHelpContext();
|
||||
|
||||
const availableUsers = useMemo(() =>
|
||||
{
|
||||
const users: Map<number, IReportedUser> = new Map();
|
||||
|
||||
GetChatHistory().chats.forEach(chat =>
|
||||
chatHistory.forEach(chat =>
|
||||
{
|
||||
if((chat.type === ChatEntryType.TYPE_CHAT) && (chat.entityType === RoomObjectType.USER) && (chat.entityId !== GetSessionDataManager().userId))
|
||||
{
|
||||
@ -28,7 +27,7 @@ export const SelectReportedUserView: FC<{}> = props =>
|
||||
});
|
||||
|
||||
return Array.from(users.values());
|
||||
}, []);
|
||||
}, [ chatHistory ]);
|
||||
|
||||
const submitUser = () =>
|
||||
{
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { BadgePointLimitsEvent, ILinkEventTracker, IRoomSession, RoomEngineObjectEvent, RoomEngineObjectPlacedEvent, RoomPreviewer, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { AddEventLinkTracker, GetLocalization, GetRoomEngine, LocalizeText, RemoveLinkEventTracker, UnseenItemCategory } from '../../api';
|
||||
import { isObjectMoverRequested, setObjectMoverRequested } from '../../api/inventory/InventoryUtilities';
|
||||
import { AddEventLinkTracker, GetLocalization, GetRoomEngine, isObjectMoverRequested, LocalizeText, RemoveLinkEventTracker, setObjectMoverRequested, UnseenItemCategory } from '../../api';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
|
||||
import { useInventoryTrade, useInventoryUnseenTracker, useMessageEvent, useRoomEngineEvent, useRoomSessionManagerEvent } from '../../hooks';
|
||||
import { InventoryBadgeView } from './views/badge/InventoryBadgeView';
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { FC, useEffect, useMemo, useState } from 'react';
|
||||
import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized';
|
||||
import { GetSessionDataManager, RoomObjectItem } from '../../../../api';
|
||||
import { LocalizeText } from '../../../../api/utils';
|
||||
import { GetSessionDataManager, LocalizeText, RoomObjectItem } from '../../../../api';
|
||||
import { Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||
|
||||
interface ChooserWidgetViewProps
|
||||
|
@ -28,7 +28,7 @@ export const FurnitureStickieView: FC<{}> = props =>
|
||||
if(objectId === -1) return null;
|
||||
|
||||
return (
|
||||
<DraggableWindow handleSelector=".drag-handler" windowPosition={ DraggableWindowPosition.NOTHING }>
|
||||
<DraggableWindow handleSelector=".drag-handler" windowPosition={ DraggableWindowPosition.TOP_LEFT }>
|
||||
<div className={ 'nitro-stickie nitro-stickie-image stickie-' + getStickieColorName(color) }>
|
||||
<div className="d-flex align-items-center stickie-header drag-handler">
|
||||
<div className="d-flex align-items-center flex-grow-1 h-100">
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { RedeemItemClothingComposer, RoomObjectCategory, UserFigureComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { FurniCategory, GetAvatarRenderManager, GetConnection, GetFurnitureDataForRoomObject, GetSessionDataManager, LocalizeText } from '../../../../../api';
|
||||
import { FigureData, FurniCategory, GetAvatarRenderManager, GetConnection, GetFurnitureDataForRoomObject, GetSessionDataManager, LocalizeText } from '../../../../../api';
|
||||
import { Base, Button, Column, Flex, LayoutAvatarImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
|
||||
import { useRoom } from '../../../../../hooks';
|
||||
import { FigureData } from '../../../../avatar-editor/common/FigureData';
|
||||
|
||||
interface PurchasableClothingConfirmViewProps
|
||||
{
|
||||
|
@ -1,38 +0,0 @@
|
||||
import { Triggerable } from '@nitrots/nitro-renderer';
|
||||
import { createContext, Dispatch, FC, ProviderProps, SetStateAction, useContext } from 'react';
|
||||
|
||||
export interface IWiredContext
|
||||
{
|
||||
trigger: Triggerable;
|
||||
setTrigger: Dispatch<SetStateAction<Triggerable>>;
|
||||
intParams: number[],
|
||||
setIntParams: Dispatch<SetStateAction<number[]>>;
|
||||
stringParam: string;
|
||||
setStringParam: Dispatch<SetStateAction<string>>;
|
||||
furniIds: number[];
|
||||
setFurniIds: Dispatch<SetStateAction<number[]>>;
|
||||
actionDelay: number;
|
||||
setActionDelay: Dispatch<SetStateAction<number>>;
|
||||
saveWired: () => void;
|
||||
}
|
||||
|
||||
const WiredContext = createContext<IWiredContext>({
|
||||
trigger: null,
|
||||
setTrigger: null,
|
||||
intParams: null,
|
||||
setIntParams: null,
|
||||
stringParam: null,
|
||||
setStringParam: null,
|
||||
furniIds: null,
|
||||
setFurniIds: null,
|
||||
actionDelay: null,
|
||||
setActionDelay: null,
|
||||
saveWired: null
|
||||
});
|
||||
|
||||
export const WiredContextProvider: FC<ProviderProps<IWiredContext>> = props =>
|
||||
{
|
||||
return <WiredContext.Provider value={ props.value }>{ props.children }</WiredContext.Provider>
|
||||
}
|
||||
|
||||
export const useWiredContext = () => useContext(WiredContext);
|
@ -1,68 +0,0 @@
|
||||
import { WiredFurniActionEvent, WiredFurniConditionEvent, WiredFurniTriggerEvent, WiredOpenEvent, WiredRewardResultMessageEvent, WiredSaveSuccessEvent, WiredValidationErrorEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText, NotificationAlertType, NotificationUtilities } from '../../api';
|
||||
import { useMessageEvent } from '../../hooks';
|
||||
import { useWiredContext } from './WiredContext';
|
||||
|
||||
export const WiredMessageHandler: FC<{}> = props =>
|
||||
{
|
||||
const { setTrigger = null } = useWiredContext();
|
||||
|
||||
const onWiredFurniActionEvent = useCallback((event: WiredFurniActionEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setTrigger(parser.definition);
|
||||
}, [ setTrigger ]);
|
||||
|
||||
const onWiredFurniConditionEvent = useCallback((event: WiredFurniConditionEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setTrigger(parser.definition);
|
||||
}, [ setTrigger ]);
|
||||
|
||||
const onWiredFurniTriggerEvent = useCallback((event: WiredFurniTriggerEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setTrigger(parser.definition);
|
||||
}, [ setTrigger ]);
|
||||
|
||||
const onWiredOpenEvent = useCallback((event: WiredOpenEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
console.log(parser);
|
||||
}, []);
|
||||
|
||||
const onWiredRewardResultMessageEvent = useCallback((event: WiredRewardResultMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
console.log(parser);
|
||||
}, []);
|
||||
|
||||
const onWiredSaveSuccessEvent = useCallback((event: WiredSaveSuccessEvent) =>
|
||||
{
|
||||
setTrigger(null);
|
||||
}, [ setTrigger ]);
|
||||
|
||||
const onWiredValidationErrorEvent = useCallback((event: WiredValidationErrorEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
NotificationUtilities.simpleAlert(parser.info, NotificationAlertType.DEFAULT, null, null, LocalizeText('error.title'));
|
||||
console.log(parser);
|
||||
}, []);
|
||||
|
||||
useMessageEvent(WiredFurniActionEvent, onWiredFurniActionEvent);
|
||||
useMessageEvent(WiredFurniConditionEvent, onWiredFurniConditionEvent);
|
||||
useMessageEvent(WiredFurniTriggerEvent, onWiredFurniTriggerEvent);
|
||||
useMessageEvent(WiredOpenEvent, onWiredOpenEvent);
|
||||
useMessageEvent(WiredRewardResultMessageEvent, onWiredRewardResultMessageEvent);
|
||||
useMessageEvent(WiredSaveSuccessEvent, onWiredSaveSuccessEvent);
|
||||
useMessageEvent(WiredValidationErrorEvent, onWiredValidationErrorEvent);
|
||||
|
||||
return null;
|
||||
};
|
@ -1,58 +1,21 @@
|
||||
import { ConditionDefinition, Triggerable, TriggerDefinition, UpdateActionMessageComposer, UpdateConditionMessageComposer, UpdateTriggerMessageComposer, WiredActionDefinition } from '@nitrots/nitro-renderer';
|
||||
import { FC, useState } from 'react';
|
||||
import { IsOwnerOfFloorFurniture, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../api';
|
||||
import { GetWiredLayout } from './common/GetWiredLayout';
|
||||
import { WiredContextProvider } from './WiredContext';
|
||||
import { WiredMessageHandler } from './WiredMessageHandler';
|
||||
import { ConditionDefinition, TriggerDefinition, WiredActionDefinition } from '@nitrots/nitro-renderer';
|
||||
import { FC } from 'react';
|
||||
import { useWired } from '../../hooks';
|
||||
import { WiredActionLayoutView } from './views/actions/WiredActionLayoutView';
|
||||
import { WiredConditionLayoutView } from './views/conditions/WiredConditionLayoutView';
|
||||
import { WiredTriggerLayoutView } from './views/triggers/WiredTriggerLayoutView';
|
||||
|
||||
export const WiredView: FC<{}> = props =>
|
||||
{
|
||||
const [ trigger, setTrigger ] = useState<Triggerable>(null);
|
||||
const [ intParams, setIntParams ] = useState<number[]>([]);
|
||||
const [ stringParam, setStringParam ] = useState<string>('');
|
||||
const [ furniIds, setFurniIds ] = useState<number[]>([]);
|
||||
const [ actionDelay, setActionDelay ] = useState<number>(0);
|
||||
const { trigger = null } = useWired();
|
||||
|
||||
const saveWired = () =>
|
||||
{
|
||||
const save = (trigger: Triggerable) =>
|
||||
{
|
||||
if(!trigger) return;
|
||||
if(!trigger) return null;
|
||||
|
||||
if(trigger instanceof WiredActionDefinition)
|
||||
{
|
||||
SendMessageComposer(new UpdateActionMessageComposer(trigger.id, intParams, stringParam, furniIds, actionDelay, trigger.stuffTypeSelectionCode));
|
||||
}
|
||||
if(trigger instanceof WiredActionDefinition) return WiredActionLayoutView(trigger.code);
|
||||
|
||||
else if(trigger instanceof TriggerDefinition)
|
||||
{
|
||||
SendMessageComposer(new UpdateTriggerMessageComposer(trigger.id, intParams, stringParam, furniIds, trigger.stuffTypeSelectionCode));
|
||||
}
|
||||
if(trigger instanceof TriggerDefinition) return WiredTriggerLayoutView(trigger.code);
|
||||
|
||||
else if(trigger instanceof ConditionDefinition)
|
||||
{
|
||||
SendMessageComposer(new UpdateConditionMessageComposer(trigger.id, intParams, stringParam, furniIds, trigger.stuffTypeSelectionCode));
|
||||
}
|
||||
}
|
||||
if(trigger instanceof ConditionDefinition) return WiredConditionLayoutView(trigger.code);
|
||||
|
||||
if(!IsOwnerOfFloorFurniture(trigger.id))
|
||||
{
|
||||
NotificationUtilities.confirm(LocalizeText('wiredfurni.nonowner.change.confirm.body'), () =>
|
||||
{
|
||||
save(trigger)
|
||||
}, null, null, null, LocalizeText('wiredfurni.nonowner.change.confirm.title'));
|
||||
}
|
||||
else
|
||||
{
|
||||
save(trigger);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<WiredContextProvider value={ { trigger, setTrigger, intParams, setIntParams, stringParam, setStringParam, furniIds, setFurniIds, actionDelay, setActionDelay, saveWired } }>
|
||||
<WiredMessageHandler />
|
||||
{ (trigger !== null) &&
|
||||
GetWiredLayout(trigger) }
|
||||
</WiredContextProvider>
|
||||
);
|
||||
return null;
|
||||
};
|
||||
|
@ -1,85 +0,0 @@
|
||||
import { WiredActionLayout } from '../../../api';
|
||||
import { WiredActionBotChangeFigureView } from '../views/actions/WiredActionBotChangeFigureView';
|
||||
import { WiredActionBotFollowAvatarView } from '../views/actions/WiredActionBotFollowAvatarView';
|
||||
import { WiredActionBotGiveHandItemView } from '../views/actions/WiredActionBotGiveHandItemView';
|
||||
import { WiredActionBotMoveView } from '../views/actions/WiredActionBotMoveView';
|
||||
import { WiredActionBotTalkToAvatarView } from '../views/actions/WiredActionBotTalkToAvatarView';
|
||||
import { WiredActionBotTalkView } from '../views/actions/WiredActionBotTalkView';
|
||||
import { WiredActionBotTeleportView } from '../views/actions/WiredActionBotTeleportView';
|
||||
import { WiredActionCallAnotherStackView } from '../views/actions/WiredActionCallAnotherStackView';
|
||||
import { WiredActionChaseView } from '../views/actions/WiredActionChaseView';
|
||||
import { WiredActionChatView } from '../views/actions/WiredActionChatView';
|
||||
import { WiredActionFleeView } from '../views/actions/WiredActionFleeView';
|
||||
import { WiredActionGiveRewardView } from '../views/actions/WiredActionGiveRewardView';
|
||||
import { WiredActionGiveScoreToPredefinedTeamView } from '../views/actions/WiredActionGiveScoreToPredefinedTeamView';
|
||||
import { WiredActionGiveScoreView } from '../views/actions/WiredActionGiveScoreView';
|
||||
import { WiredActionJoinTeamView } from '../views/actions/WiredActionJoinTeamView';
|
||||
import { WiredActionKickFromRoomView } from '../views/actions/WiredActionKickFromRoomView';
|
||||
import { WiredActionLeaveTeamView } from '../views/actions/WiredActionLeaveTeamView';
|
||||
import { WiredActionMoveAndRotateFurniView } from '../views/actions/WiredActionMoveAndRotateFurniView';
|
||||
import { WiredActionMoveFurniToView } from '../views/actions/WiredActionMoveFurniToView';
|
||||
import { WiredActionMoveFurniView } from '../views/actions/WiredActionMoveFurniView';
|
||||
import { WiredActionMuteUserView } from '../views/actions/WiredActionMuteUserView';
|
||||
import { WiredActionResetView } from '../views/actions/WiredActionResetView';
|
||||
import { WiredActionSetFurniStateToView } from '../views/actions/WiredActionSetFurniStateToView';
|
||||
import { WiredActionTeleportView } from '../views/actions/WiredActionTeleportView';
|
||||
import { WiredActionToggleFurniStateView } from '../views/actions/WiredActionToggleFurniStateView';
|
||||
|
||||
export const GetWiredActionLayout = (code: number) =>
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
case WiredActionLayout.BOT_CHANGE_FIGURE:
|
||||
return <WiredActionBotChangeFigureView />;
|
||||
case WiredActionLayout.BOT_FOLLOW_AVATAR:
|
||||
return <WiredActionBotFollowAvatarView />;
|
||||
case WiredActionLayout.BOT_GIVE_HAND_ITEM:
|
||||
return <WiredActionBotGiveHandItemView />;
|
||||
case WiredActionLayout.BOT_MOVE:
|
||||
return <WiredActionBotMoveView />;
|
||||
case WiredActionLayout.BOT_TALK:
|
||||
return <WiredActionBotTalkView />;
|
||||
case WiredActionLayout.BOT_TALK_DIRECT_TO_AVTR:
|
||||
return <WiredActionBotTalkToAvatarView />;
|
||||
case WiredActionLayout.BOT_TELEPORT:
|
||||
return <WiredActionBotTeleportView />;
|
||||
case WiredActionLayout.CALL_ANOTHER_STACK:
|
||||
return <WiredActionCallAnotherStackView />;
|
||||
case WiredActionLayout.CHASE:
|
||||
return <WiredActionChaseView />;
|
||||
case WiredActionLayout.CHAT:
|
||||
return <WiredActionChatView />;
|
||||
case WiredActionLayout.FLEE:
|
||||
return <WiredActionFleeView />;
|
||||
case WiredActionLayout.GIVE_REWARD:
|
||||
return <WiredActionGiveRewardView />;
|
||||
case WiredActionLayout.GIVE_SCORE:
|
||||
return <WiredActionGiveScoreView />;
|
||||
case WiredActionLayout.GIVE_SCORE_TO_PREDEFINED_TEAM:
|
||||
return <WiredActionGiveScoreToPredefinedTeamView />;
|
||||
case WiredActionLayout.JOIN_TEAM:
|
||||
return <WiredActionJoinTeamView />;
|
||||
case WiredActionLayout.KICK_FROM_ROOM:
|
||||
return <WiredActionKickFromRoomView />;
|
||||
case WiredActionLayout.LEAVE_TEAM:
|
||||
return <WiredActionLeaveTeamView />;
|
||||
case WiredActionLayout.MOVE_FURNI:
|
||||
return <WiredActionMoveFurniView />;
|
||||
case WiredActionLayout.MOVE_AND_ROTATE_FURNI:
|
||||
return <WiredActionMoveAndRotateFurniView />;
|
||||
case WiredActionLayout.MOVE_FURNI_TO:
|
||||
return <WiredActionMoveFurniToView />;
|
||||
case WiredActionLayout.MUTE_USER:
|
||||
return <WiredActionMuteUserView />;
|
||||
case WiredActionLayout.RESET:
|
||||
return <WiredActionResetView />;
|
||||
case WiredActionLayout.SET_FURNI_STATE:
|
||||
return <WiredActionSetFurniStateToView />;
|
||||
case WiredActionLayout.TELEPORT:
|
||||
return <WiredActionTeleportView />;
|
||||
case WiredActionLayout.TOGGLE_FURNI_STATE:
|
||||
return <WiredActionToggleFurniStateView />;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user