From 6a2821389688f5e75b3ddda2e05811dec2b2fbdb Mon Sep 17 00:00:00 2001 From: Bill Date: Tue, 21 Sep 2021 21:48:00 -0400 Subject: [PATCH] Messenger updates --- src/api/friends/OpenMessengerChat.ts | 5 +- .../friends/FriendsMessengerIconEvent.ts | 23 ++ src/events/friends/index.ts | 1 + .../card/content/NitroCardContentView.scss | 1 + .../catalog/common/AttemptCatalogPlacement.ts | 30 ++ .../catalog/common/IsCatalogOfferDraggable.ts | 8 + .../views/page/offer/CatalogPageOfferView.tsx | 15 +- .../views/page/product/CatalogProductView.tsx | 2 +- src/views/friends/FriendsMessageHandler.tsx | 23 +- src/views/friends/common/MessengerChat.ts | 49 --- .../common/MessengerChatMessageGroup.ts | 35 -- src/views/friends/common/MessengerThread.ts | 83 ++++ ...rChatMessage.ts => MessengerThreadChat.ts} | 25 +- .../common/MessengerThreadChatGroup.ts | 28 ++ src/views/friends/reducers/FriendsReducer.tsx | 64 +-- .../FriendsMessengerThreadGroup.tsx | 48 +++ .../FriendsMessengerThreadGroup.types.ts | 8 + .../FriendsMessengerThreadView.tsx | 17 + .../FriendsMessengerThreadView.types.ts | 6 + .../views/messenger/FriendsMessengerView.scss | 1 + .../views/messenger/FriendsMessengerView.tsx | 365 ++++++++++-------- .../chat/message/ChatWidgetMessageView.scss | 4 +- .../shared/avatar-image/AvatarImage.scss | 6 + .../shared/avatar-image/AvatarImageView.tsx | 11 +- .../room-previewer/RoomPreviewerView.scss | 1 - src/views/toolbar/ToolbarView.scss | 25 +- src/views/toolbar/ToolbarView.tsx | 48 ++- src/views/toolbar/ToolbarView.types.ts | 1 + tsconfig.json | 2 +- 29 files changed, 569 insertions(+), 366 deletions(-) create mode 100644 src/events/friends/FriendsMessengerIconEvent.ts create mode 100644 src/views/catalog/common/AttemptCatalogPlacement.ts create mode 100644 src/views/catalog/common/IsCatalogOfferDraggable.ts delete mode 100644 src/views/friends/common/MessengerChat.ts delete mode 100644 src/views/friends/common/MessengerChatMessageGroup.ts create mode 100644 src/views/friends/common/MessengerThread.ts rename src/views/friends/common/{MessengerChatMessage.ts => MessengerThreadChat.ts} (51%) create mode 100644 src/views/friends/common/MessengerThreadChatGroup.ts create mode 100644 src/views/friends/views/messenger-thread-group/FriendsMessengerThreadGroup.tsx create mode 100644 src/views/friends/views/messenger-thread-group/FriendsMessengerThreadGroup.types.ts create mode 100644 src/views/friends/views/messenger-thread/FriendsMessengerThreadView.tsx create mode 100644 src/views/friends/views/messenger-thread/FriendsMessengerThreadView.types.ts diff --git a/src/api/friends/OpenMessengerChat.ts b/src/api/friends/OpenMessengerChat.ts index 08520b1b..0b8ab554 100644 --- a/src/api/friends/OpenMessengerChat.ts +++ b/src/api/friends/OpenMessengerChat.ts @@ -1,6 +1,7 @@ import { CreateLinkEvent } from '..'; -export function OpenMessengerChat(friendId: number): void +export function OpenMessengerChat(friendId: number = -1): void { - CreateLinkEvent(`friends/messenger/${friendId}`); + if(friendId === -1) CreateLinkEvent('friends/messenger/open'); + else CreateLinkEvent(`friends/messenger/${friendId}`); } diff --git a/src/events/friends/FriendsMessengerIconEvent.ts b/src/events/friends/FriendsMessengerIconEvent.ts new file mode 100644 index 00000000..602eb726 --- /dev/null +++ b/src/events/friends/FriendsMessengerIconEvent.ts @@ -0,0 +1,23 @@ +import { NitroEvent } from '@nitrots/nitro-renderer'; + +export class FriendsMessengerIconEvent extends NitroEvent +{ + public static UPDATE_ICON: string = 'FMIE_UPDATE_ICON'; + public static HIDE_ICON: number = 0; + public static SHOW_ICON: number = 1; + public static UNREAD_ICON: number = 2; + + private _iconType: number; + + constructor(type: string, subType: number = FriendsMessengerIconEvent.SHOW_ICON) + { + super(type); + + this._iconType = subType; + } + + public get iconType(): number + { + return this._iconType; + } +} diff --git a/src/events/friends/index.ts b/src/events/friends/index.ts index 9a4bb3ed..2f3699c3 100644 --- a/src/events/friends/index.ts +++ b/src/events/friends/index.ts @@ -1,4 +1,5 @@ export * from './FriendEnteredRoomEvent'; export * from './FriendListContentEvent'; export * from './FriendsEvent'; +export * from './FriendsMessengerIconEvent'; export * from './FriendsSendFriendRequestEvent'; diff --git a/src/layout/card/content/NitroCardContentView.scss b/src/layout/card/content/NitroCardContentView.scss index 9ffd6fe9..4cbe6ee3 100644 --- a/src/layout/card/content/NitroCardContentView.scss +++ b/src/layout/card/content/NitroCardContentView.scss @@ -1,4 +1,5 @@ .content-area { + height: 100%; padding-top: $container-padding-x; padding-bottom: $container-padding-x; overflow: auto; diff --git a/src/views/catalog/common/AttemptCatalogPlacement.ts b/src/views/catalog/common/AttemptCatalogPlacement.ts new file mode 100644 index 00000000..af342ee3 --- /dev/null +++ b/src/views/catalog/common/AttemptCatalogPlacement.ts @@ -0,0 +1,30 @@ +import { CatalogPageMessageOfferData, RoomObjectCategory, RoomObjectPlacementSource } from '@nitrots/nitro-renderer'; +import { GetRoomEngine } from '../../../api'; +import { IsCatalogOfferDraggable } from './IsCatalogOfferDraggable'; +import { ProductTypeEnum } from './ProductTypeEnum'; + +export const AttemptCatalogPlacement = (offer: CatalogPageMessageOfferData) => +{ + if(!IsCatalogOfferDraggable(offer)) return; + + const product = offer.products[0]; + + let category: number = -1; + + switch(product.productType) + { + case ProductTypeEnum.FLOOR: + category = RoomObjectCategory.FLOOR; + break; + case ProductTypeEnum.WALL: + category = RoomObjectCategory.WALL; + break; + } + + if(category === -1) return; + + if(GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.CATALOG, -(offer.offerId), category, product.furniClassId, (product.extraParam) ? product.extraParam.toString() : null)) + { + + } +} diff --git a/src/views/catalog/common/IsCatalogOfferDraggable.ts b/src/views/catalog/common/IsCatalogOfferDraggable.ts new file mode 100644 index 00000000..174ce4d0 --- /dev/null +++ b/src/views/catalog/common/IsCatalogOfferDraggable.ts @@ -0,0 +1,8 @@ +import { CatalogPageMessageOfferData, RoomControllerLevel } from '@nitrots/nitro-renderer'; +import { GetRoomSession } from '../../../api'; +import { ProductTypeEnum } from './ProductTypeEnum'; + +export const IsCatalogOfferDraggable = (offer: CatalogPageMessageOfferData) => +{ + return ((GetRoomSession().isRoomOwner || (GetRoomSession().isGuildRoom && (GetRoomSession().controllerLevel >= RoomControllerLevel.GUILD_MEMBER))) && (offer.products.length === 1) && (offer.products[0].productType !== ProductTypeEnum.EFFECT) && (offer.products[0].productType !== ProductTypeEnum.HABBO_CLUB)) +} diff --git a/src/views/catalog/views/page/offer/CatalogPageOfferView.tsx b/src/views/catalog/views/page/offer/CatalogPageOfferView.tsx index 89f6b90f..980ee8e7 100644 --- a/src/views/catalog/views/page/offer/CatalogPageOfferView.tsx +++ b/src/views/catalog/views/page/offer/CatalogPageOfferView.tsx @@ -1,5 +1,5 @@ import { MouseEventType } from '@nitrots/nitro-renderer'; -import { FC, MouseEvent, useCallback } from 'react'; +import { FC, MouseEvent, useCallback, useState } from 'react'; import { useCatalogContext } from '../../../context/CatalogContext'; import { CatalogActions } from '../../../reducers/CatalogReducer'; import { CatalogProductView } from '../product/CatalogProductView'; @@ -8,6 +8,7 @@ import { CatalogPageOfferViewProps } from './CatalogPageOfferView.types'; export const CatalogPageOfferView: FC = props => { const { isActive = false, offer = null } = props; + const [ isMouseDown, setMouseDown ] = useState(false); const { dispatchCatalogState = null } = useCatalogContext(); const onMouseEvent = useCallback((event: MouseEvent) => @@ -24,8 +25,18 @@ export const CatalogPageOfferView: FC = props => } }); return; + case MouseEventType.MOUSE_DOWN: + console.log('ye') + setMouseDown(true); + return; + case MouseEventType.MOUSE_UP: + setMouseDown(false); + return; + case MouseEventType.ROLL_OUT: + if(!isMouseDown || !isActive) return; + return; } - }, [ isActive, offer, dispatchCatalogState ]); + }, [ isActive, offer, isMouseDown, dispatchCatalogState ]); const product = ((offer.products && offer.products[0]) || null); diff --git a/src/views/catalog/views/page/product/CatalogProductView.tsx b/src/views/catalog/views/page/product/CatalogProductView.tsx index 684488d0..2bb1c543 100644 --- a/src/views/catalog/views/page/product/CatalogProductView.tsx +++ b/src/views/catalog/views/page/product/CatalogProductView.tsx @@ -65,7 +65,7 @@ export const CatalogProductView: FC = props => return (
-
+
{ !imageUrl && (product.productType === ProductTypeEnum.ROBOT) && } { (product.productCount > 1) && { product.productCount } } diff --git a/src/views/friends/FriendsMessageHandler.tsx b/src/views/friends/FriendsMessageHandler.tsx index 479fc961..ce84725e 100644 --- a/src/views/friends/FriendsMessageHandler.tsx +++ b/src/views/friends/FriendsMessageHandler.tsx @@ -1,8 +1,6 @@ -import { FriendListFragmentEvent, FriendListUpdateEvent, FriendRequestsEvent, GetFriendRequestsComposer, MessengerInitEvent, NewConsoleMessageEvent } from '@nitrots/nitro-renderer'; +import { FriendListFragmentEvent, FriendListUpdateEvent, FriendRequestsEvent, GetFriendRequestsComposer, MessengerInitEvent } from '@nitrots/nitro-renderer'; import { FC, useCallback } from 'react'; -import { GetSessionDataManager } from '../../api'; import { CreateMessageHook, SendMessageHook } from '../../hooks/messages/message-event'; -import { MessengerChatMessage } from './common/MessengerChatMessage'; import { MessengerSettings } from './common/MessengerSettings'; import { useFriendsContext } from './context/FriendsContext'; import { FriendsActions } from './reducers/FriendsReducer'; @@ -10,7 +8,6 @@ import { FriendsActions } from './reducers/FriendsReducer'; export const FriendsMessageHandler: FC<{}> = props => { const { friendsState = null, dispatchFriendsState = null } = useFriendsContext(); - const { activeChats = [] } = friendsState; const onMessengerInitEvent = useCallback((event: MessengerInitEvent) => { @@ -66,28 +63,10 @@ export const FriendsMessageHandler: FC<{}> = props => }); }, [ dispatchFriendsState ]); - const onNewConsoleMessageEvent = useCallback((event: NewConsoleMessageEvent) => - { - const parser = event.getParser(); - - let userId = parser.senderId; - - if(userId === GetSessionDataManager().userId) userId = 0; - - dispatchFriendsState({ - type: FriendsActions.ADD_CHAT_MESSAGE, - payload: { - chatMessage: new MessengerChatMessage(MessengerChatMessage.MESSAGE, userId, parser.messageText, parser.secondsSinceSent, parser.extraData), - boolValue: true - } - }); - }, [ dispatchFriendsState ]); - CreateMessageHook(MessengerInitEvent, onMessengerInitEvent); CreateMessageHook(FriendListFragmentEvent, onFriendsFragmentEvent); CreateMessageHook(FriendListUpdateEvent, onFriendsUpdateEvent); CreateMessageHook(FriendRequestsEvent, onFriendRequestsEvent); - CreateMessageHook(NewConsoleMessageEvent, onNewConsoleMessageEvent); return null; } diff --git a/src/views/friends/common/MessengerChat.ts b/src/views/friends/common/MessengerChat.ts deleted file mode 100644 index 4b49d0ae..00000000 --- a/src/views/friends/common/MessengerChat.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { MessengerChatMessage } from './MessengerChatMessage'; -import { MessengerChatMessageGroup } from './MessengerChatMessageGroup'; -export class MessengerChat -{ - private _friendId: number; - private _isRead: boolean; - private _messageGroups: MessengerChatMessageGroup[]; - - constructor(friendId: number) - { - this._friendId = friendId; - this._isRead = true; - this._messageGroups = []; - } - - public addMessage(message: MessengerChatMessage, setAsNotRead: boolean = true, isSystem: boolean = false): void - { - if(!this.lastMessageGroup || this.lastMessageGroup.userId !== message.senderId || isSystem || this.lastMessageGroup.isSystem) this._messageGroups.push(new MessengerChatMessageGroup(message.senderId, isSystem)); - - this.lastMessageGroup.addMessage(message); - - if(setAsNotRead) this._isRead = false; - } - - public read(): void - { - this._isRead = true; - } - - public get friendId(): number - { - return this._friendId; - } - - public get isRead(): boolean - { - return this._isRead; - } - - public get messageGroups(): MessengerChatMessageGroup[] - { - return this._messageGroups; - } - - public get lastMessageGroup(): MessengerChatMessageGroup - { - return this._messageGroups[this._messageGroups.length - 1]; - } -} diff --git a/src/views/friends/common/MessengerChatMessageGroup.ts b/src/views/friends/common/MessengerChatMessageGroup.ts deleted file mode 100644 index 0fad7be8..00000000 --- a/src/views/friends/common/MessengerChatMessageGroup.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { MessengerChatMessage } from './MessengerChatMessage'; - -export class MessengerChatMessageGroup -{ - private _userId: number; - private _messages: MessengerChatMessage[]; - private _isSystem: boolean; - - constructor(userId: number, isSystem: boolean) - { - this._userId = userId; - this._messages = []; - this._isSystem = isSystem; - } - - public addMessage(message: MessengerChatMessage): void - { - this._messages.push(message); - } - - public get userId(): number - { - return this._userId; - } - - public get messages(): MessengerChatMessage[] - { - return this._messages; - } - - public get isSystem(): boolean - { - return this._isSystem; - } -} diff --git a/src/views/friends/common/MessengerThread.ts b/src/views/friends/common/MessengerThread.ts new file mode 100644 index 00000000..a2ee75e1 --- /dev/null +++ b/src/views/friends/common/MessengerThread.ts @@ -0,0 +1,83 @@ +import { LocalizeText } from '../../../api'; +import { MessengerFriend } from './MessengerFriend'; +import { MessengerThreadChat } from './MessengerThreadChat'; +import { MessengerThreadChatGroup } from './MessengerThreadChatGroup'; + +export class MessengerThread +{ + public static MESSAGE_RECEIVED: string = 'MT_MESSAGE_RECEIVED'; + + private _participant: MessengerFriend; + private _groups: MessengerThreadChatGroup[]; + private _lastUpdated: Date; + private _unread: boolean; + + constructor(participant: MessengerFriend, isNew: boolean = true) + { + this._participant = participant; + this._groups = []; + this._lastUpdated = new Date(); + this._unread = false; + + if(isNew) + { + this.addMessage(-1, LocalizeText('messenger.moderationinfo'), 0, null, MessengerThreadChat.SECURITY_NOTIFICATION); + + this._unread = false; + } + } + + public addMessage(senderId: number, message: string, secondsSinceSent: number = 0, extraData: string = null, type: number = 0): MessengerThreadChat + { + const group = this.getLastGroup(senderId); + + if(!group) return; + + const chat = new MessengerThreadChat(senderId, message, secondsSinceSent, extraData, type); + + group.addChat(chat); + + this._lastUpdated = new Date(); + this._unread = true; + + return chat; + } + + private getLastGroup(userId: number): MessengerThreadChatGroup + { + let group = this._groups[(this._groups.length - 1)]; + + if(group && (group.userId === userId)) return group; + + group = new MessengerThreadChatGroup(userId); + + this._groups.push(group); + + return group; + } + + public setRead(): void + { + this._unread = false; + } + + public get participant(): MessengerFriend + { + return this._participant; + } + + public get groups(): MessengerThreadChatGroup[] + { + return this._groups; + } + + public get lastUpdated(): Date + { + return this._lastUpdated; + } + + public get unread(): boolean + { + return this._unread; + } +} diff --git a/src/views/friends/common/MessengerChatMessage.ts b/src/views/friends/common/MessengerThreadChat.ts similarity index 51% rename from src/views/friends/common/MessengerChatMessage.ts rename to src/views/friends/common/MessengerThreadChat.ts index 6a0aced7..2927fecc 100644 --- a/src/views/friends/common/MessengerChatMessage.ts +++ b/src/views/friends/common/MessengerThreadChat.ts @@ -1,23 +1,25 @@ -export class MessengerChatMessage +export class MessengerThreadChat { - public static MESSAGE: number = 0; + public static CHAT: number = 0; public static ROOM_INVITE: number = 1; - public static SECURITY_ALERT: number = 2; - public static STATUS_ALERT: number = 3; + public static STATUS_NOTIFICATION: number = 2; + public static SECURITY_NOTIFICATION: number = 3; private _type: number; private _senderId: number; private _message: string; - private _sentAt: number; + private _secondsSinceSent: number; private _extraData: string; + private _date: Date; - constructor(type: number, senderId: number, message: string, sentAt: number, extraData?: string) + constructor(senderId: number, message: string, secondsSinceSent: number = 0, extraData: string = null, type: number = 0) { this._type = type; this._senderId = senderId; this._message = message; - this._sentAt = sentAt; + this._secondsSinceSent = secondsSinceSent; this._extraData = extraData; + this._date = new Date(); } public get type(): number @@ -35,13 +37,18 @@ export class MessengerChatMessage return this._message; } - public get sentAt(): number + public get secondsSinceSent(): number { - return this._sentAt; + return this._secondsSinceSent; } public get extraData(): string { return this._extraData; } + + public get date(): Date + { + return this._date; + } } diff --git a/src/views/friends/common/MessengerThreadChatGroup.ts b/src/views/friends/common/MessengerThreadChatGroup.ts new file mode 100644 index 00000000..661dcb07 --- /dev/null +++ b/src/views/friends/common/MessengerThreadChatGroup.ts @@ -0,0 +1,28 @@ +import { MessengerThreadChat } from './MessengerThreadChat'; + +export class MessengerThreadChatGroup +{ + private _userId: number; + private _chats: MessengerThreadChat[]; + + constructor(userId: number) + { + this._userId = userId; + this._chats = []; + } + + public addChat(message: MessengerThreadChat): void + { + this._chats.push(message); + } + + public get userId(): number + { + return this._userId; + } + + public get chats(): MessengerThreadChat[] + { + return this._chats; + } +} diff --git a/src/views/friends/reducers/FriendsReducer.tsx b/src/views/friends/reducers/FriendsReducer.tsx index 82f2e734..1901bb49 100644 --- a/src/views/friends/reducers/FriendsReducer.tsx +++ b/src/views/friends/reducers/FriendsReducer.tsx @@ -1,7 +1,5 @@ import { FriendListUpdateParser, FriendParser, FriendRequestData } from '@nitrots/nitro-renderer'; import { Reducer } from 'react'; -import { MessengerChat } from '../common/MessengerChat'; -import { MessengerChatMessage } from '../common/MessengerChatMessage'; import { MessengerFriend } from '../common/MessengerFriend'; import { MessengerRequest } from '../common/MessengerRequest'; import { MessengerSettings } from '../common/MessengerSettings'; @@ -18,8 +16,6 @@ export interface IFriendsState settings: MessengerSettings; friends: MessengerFriend[]; requests: MessengerRequest[]; - activeChats: MessengerChat[]; - firstChatEverOpen: boolean; } export interface IFriendsAction @@ -30,8 +26,6 @@ export interface IFriendsAction fragment?: FriendParser[]; update?: FriendListUpdateParser; requests?: FriendRequestData[]; - chats?: MessengerChat[]; - chatMessage?: MessengerChatMessage; numberValue?: number; boolValue?: boolean; } @@ -44,17 +38,12 @@ export class FriendsActions public static PROCESS_FRAGMENT: string = 'FA_PROCESS_FRAGMENT'; public static PROCESS_UPDATE: string = 'FA_PROCESS_UPDATE'; public static PROCESS_REQUESTS: string = 'FA_PROCESS_REQUESTS'; - public static SET_ACTIVE_CHATS: string = 'FA_SET_ACTIVE_CHATS'; - public static SET_CHAT_READ: string = 'FA_SET_CHAT_READ'; - public static ADD_CHAT_MESSAGE: string = 'FA_ADD_CHAT_MESSAGE'; } export const initialFriends: IFriendsState = { settings: null, friends: [], - requests: [], - activeChats: [], - firstChatEverOpen: false + requests: [] } export const FriendsReducer: Reducer = (state, action) => @@ -108,11 +97,17 @@ export const FriendsReducer: Reducer = (state, ac { const index = friends.findIndex(existingFriend => (existingFriend.id === friend.id)); - const newFriend = new MessengerFriend(); - newFriend.populate(friend); + if(index === -1) + { + const newFriend = new MessengerFriend(); + newFriend.populate(friend); - if(index > -1) friends[index] = newFriend; - else friends.unshift(newFriend); + friends.unshift(newFriend); + } + else + { + friends[index].populate(friend); + } } for(const friend of update.addedFriends) processUpdate(friend); @@ -146,43 +141,6 @@ export const FriendsReducer: Reducer = (state, ac return { ...state, requests }; } - case FriendsActions.SET_ACTIVE_CHATS: { - const activeChats = (action.payload.chats || []); - - if(!state.firstChatEverOpen && activeChats.length > 0) activeChats[0].addMessage(new MessengerChatMessage(MessengerChatMessage.SECURITY_ALERT, 0, null, 0), false, true); - - return { ...state, activeChats, firstChatEverOpen: true }; - } - case FriendsActions.SET_CHAT_READ: { - const friendId = action.payload.numberValue; - - const activeChats = Array.from(state.activeChats); - - let activeChatIndex = activeChats.findIndex(c => c.friendId === friendId); - - if(activeChatIndex > -1) activeChats[activeChatIndex].read(); - - return { ...state, activeChats }; - } - case FriendsActions.ADD_CHAT_MESSAGE: { - const message = action.payload.chatMessage; - const toFriendId = action.payload.numberValue; - const setAsNotRead = action.payload.boolValue; - - const activeChats = Array.from(state.activeChats); - - let activeChatIndex = activeChats.findIndex(c => c.friendId === toFriendId ? toFriendId : message.senderId); - - if(activeChatIndex === -1) - { - activeChats.push(new MessengerChat(message.senderId)); - activeChatIndex = activeChats.length - 1; - } - - activeChats[activeChatIndex].addMessage(message, setAsNotRead); - - return { ...state, activeChats }; - } default: return state; } diff --git a/src/views/friends/views/messenger-thread-group/FriendsMessengerThreadGroup.tsx b/src/views/friends/views/messenger-thread-group/FriendsMessengerThreadGroup.tsx new file mode 100644 index 00000000..b0d30ea7 --- /dev/null +++ b/src/views/friends/views/messenger-thread-group/FriendsMessengerThreadGroup.tsx @@ -0,0 +1,48 @@ +import { FC } from 'react'; +import { GetSessionDataManager } from '../../../../api'; +import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView'; +import { MessengerThreadChat } from '../../common/MessengerThreadChat'; +import { FriendsMessengerThreadGroupProps } from './FriendsMessengerThreadGroup.types'; + +export const FriendsMessengerThreadGroup: FC = props => +{ + const { thread = null, group = null } = props; + + if(!thread || !group) return null; + + if(group.userId === -1) + { + return ( +
+ { group.chats.map((chat, index) => + { + return ( +
+ { chat.type === MessengerThreadChat.SECURITY_NOTIFICATION && +
+ +
{ chat.message }
+
} +
+ ); + }) } +
+ ); + } + + return ( +
+ { (group.userId > 0) && +
+ +
} +
+ { group.chats.map((chat, index) =>
{ chat.message }
) } +
+ { (group.userId === 0) && +
+ +
} +
+ ); +} diff --git a/src/views/friends/views/messenger-thread-group/FriendsMessengerThreadGroup.types.ts b/src/views/friends/views/messenger-thread-group/FriendsMessengerThreadGroup.types.ts new file mode 100644 index 00000000..12a0ed17 --- /dev/null +++ b/src/views/friends/views/messenger-thread-group/FriendsMessengerThreadGroup.types.ts @@ -0,0 +1,8 @@ +import { MessengerThread } from '../../common/MessengerThread'; +import { MessengerThreadChatGroup } from '../../common/MessengerThreadChatGroup'; + +export interface FriendsMessengerThreadGroupProps +{ + thread: MessengerThread; + group: MessengerThreadChatGroup; +} diff --git a/src/views/friends/views/messenger-thread/FriendsMessengerThreadView.tsx b/src/views/friends/views/messenger-thread/FriendsMessengerThreadView.tsx new file mode 100644 index 00000000..3bf6326a --- /dev/null +++ b/src/views/friends/views/messenger-thread/FriendsMessengerThreadView.tsx @@ -0,0 +1,17 @@ +import { FC } from 'react'; +import { FriendsMessengerThreadGroup } from '../messenger-thread-group/FriendsMessengerThreadGroup'; +import { FriendsMessengerThreadViewProps } from './FriendsMessengerThreadView.types'; + +export const FriendsMessengerThreadView: FC = props => +{ + const { thread = null } = props; + + return ( + <> + { (thread.groups.length > 0) && thread.groups.map((group, index) => + { + return ; + }) } + + ); +} diff --git a/src/views/friends/views/messenger-thread/FriendsMessengerThreadView.types.ts b/src/views/friends/views/messenger-thread/FriendsMessengerThreadView.types.ts new file mode 100644 index 00000000..a6e0f4c4 --- /dev/null +++ b/src/views/friends/views/messenger-thread/FriendsMessengerThreadView.types.ts @@ -0,0 +1,6 @@ +import { MessengerThread } from '../../common/MessengerThread'; + +export interface FriendsMessengerThreadViewProps +{ + thread: MessengerThread; +} diff --git a/src/views/friends/views/messenger/FriendsMessengerView.scss b/src/views/friends/views/messenger/FriendsMessengerView.scss index bbfdb0aa..596ab19f 100644 --- a/src/views/friends/views/messenger/FriendsMessengerView.scss +++ b/src/views/friends/views/messenger/FriendsMessengerView.scss @@ -1,5 +1,6 @@ .nitro-friends-messenger { width: 280px; + resize: both; .friend-head { position: relative; diff --git a/src/views/friends/views/messenger/FriendsMessengerView.tsx b/src/views/friends/views/messenger/FriendsMessengerView.tsx index 882b435f..dac6a7a5 100644 --- a/src/views/friends/views/messenger/FriendsMessengerView.tsx +++ b/src/views/friends/views/messenger/FriendsMessengerView.tsx @@ -1,41 +1,134 @@ -import { FollowFriendMessageComposer, ILinkEventTracker, NitroEvent, SendMessageComposer, UserProfileComposer } from '@nitrots/nitro-renderer'; +import { FollowFriendMessageComposer, ILinkEventTracker, NewConsoleMessageEvent, SendMessageComposer, UserProfileComposer } from '@nitrots/nitro-renderer'; import { FC, KeyboardEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { AddEventLinkTracker, GetSessionDataManager, LocalizeText, RemoveLinkEventTracker } from '../../../../api'; -import { FriendsEvent } from '../../../../events/friends/FriendsEvent'; -import { SendMessageHook, useUiEvent } from '../../../../hooks'; +import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../../../api'; +import { FriendsMessengerIconEvent } from '../../../../events'; +import { BatchUpdates, CreateMessageHook, dispatchUiEvent, SendMessageHook } from '../../../../hooks'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView'; -import { MessengerChat } from '../../common/MessengerChat'; -import { MessengerChatMessage } from '../../common/MessengerChatMessage'; +import { MessengerThread } from '../../common/MessengerThread'; +import { MessengerThreadChat } from '../../common/MessengerThreadChat'; import { useFriendsContext } from '../../context/FriendsContext'; -import { FriendsActions } from '../../reducers/FriendsReducer'; +import { FriendsMessengerThreadView } from '../messenger-thread/FriendsMessengerThreadView'; export const FriendsMessengerView: FC<{}> = props => { - const { friendsState = null, dispatchFriendsState = null } = useFriendsContext(); - const { activeChats = [], friends = [] } = friendsState; - const [ isVisible, setIsVisible ] = useState(false); - const [ selectedChatIndex, setSelectedChatIndex ] = useState(0); - const [ message, setMessage ] = useState(''); - + const [ messageThreads, setMessageThreads ] = useState([]); + const [ activeThreadIndex, setActiveThreadIndex ] = useState(-1); + const [ hiddenThreadIndexes, setHiddenThreadIndexes ] = useState([]); + const [ messageText, setMessageText ] = useState(''); + const { friendsState = null } = useFriendsContext(); + const { friends = [] } = friendsState; const messagesBox = useRef(); - - const onNitroEvent = useCallback((event: NitroEvent) => - { - switch(event.type) - { - case FriendsEvent.SHOW_FRIEND_MESSENGER: - setIsVisible(true); - return; - case FriendsEvent.TOGGLE_FRIEND_MESSENGER: - setIsVisible(value => !value); - return; - } - }, []); + const [ updateValue, setUpdateValue ] = useState({}); - useUiEvent(FriendsEvent.SHOW_FRIEND_MESSENGER, onNitroEvent); - useUiEvent(FriendsEvent.TOGGLE_FRIEND_MESSENGER, onNitroEvent); + const followFriend = useCallback(() => + { + SendMessageHook(new FollowFriendMessageComposer(messageThreads[activeThreadIndex].participant.id)); + }, [ messageThreads, activeThreadIndex ]); + + const openProfile = useCallback(() => + { + SendMessageHook(new UserProfileComposer(messageThreads[activeThreadIndex].participant.id)); + }, [ messageThreads, activeThreadIndex ]); + + const getFriend = useCallback((userId: number) => + { + return ((friends.find(friend => (friend.id === userId))) || null); + }, [ friends ]); + + const visibleThreads = useMemo(() => + { + return messageThreads.filter((thread, index) => + { + if(hiddenThreadIndexes.indexOf(index) >= 0) return false; + + return true; + }); + }, [ messageThreads, hiddenThreadIndexes ]); + + const getMessageThreadWithIndex = useCallback<(userId: number) => [ number, MessengerThread ]>((userId: number) => + { + if(messageThreads.length > 0) + { + for(let i = 0; i < messageThreads.length; i++) + { + const thread = messageThreads[i]; + + if(thread.participant && (thread.participant.id === userId)) + { + const hiddenIndex = hiddenThreadIndexes.indexOf(i); + + if(hiddenIndex >= 0) + { + setHiddenThreadIndexes(prevValue => + { + const newIndexes = [ ...prevValue ]; + + newIndexes.splice(hiddenIndex, 1); + + return newIndexes; + }); + } + + return [ i, thread ]; + } + } + } + + const friend = getFriend(userId); + + if(!friend) return [ -1, null ]; + + const thread = new MessengerThread(friend); + const newThreads = [ ...messageThreads, thread ]; + + setMessageThreads(newThreads); + + return [ (newThreads.length - 1), thread ]; + }, [ messageThreads, hiddenThreadIndexes, getFriend ]); + + const onNewConsoleMessageEvent = useCallback((event: NewConsoleMessageEvent) => + { + const parser = event.getParser(); + const [ threadIndex, thread ] = getMessageThreadWithIndex(parser.senderId); + + if((threadIndex === -1) || !thread) return; + + thread.addMessage(parser.senderId, parser.messageText, parser.secondsSinceSent, parser.extraData); + + setMessageThreads(prevValue => [ ...prevValue ]); + }, [ getMessageThreadWithIndex ]); + + CreateMessageHook(NewConsoleMessageEvent, onNewConsoleMessageEvent); + + const sendMessage = useCallback(() => + { + if(!messageText || !messageText.length) return; + + if(activeThreadIndex === -1) return; + + const thread = messageThreads[activeThreadIndex]; + + if(!thread) return; + + SendMessageHook(new SendMessageComposer(thread.participant.id, messageText)); + + thread.addMessage(0, messageText, 0, null, MessengerThreadChat.CHAT); + + BatchUpdates(() => + { + setMessageThreads(prevValue => [ ...prevValue ]); + setMessageText(''); + }); + }, [ messageThreads, activeThreadIndex, messageText ]); + + const onKeyDown = useCallback((event: KeyboardEvent) => + { + if(event.key !== 'Enter') return; + + sendMessage(); + }, [ sendMessage ]); const linkReceived = useCallback((url: string) => { @@ -43,69 +136,35 @@ export const FriendsMessengerView: FC<{}> = props => if(parts.length < 3) return; - const friendId = parseInt(parts[2]); - - let existingChatIndex = activeChats.findIndex(c => c.friendId === friendId); - - if(existingChatIndex === -1) + if(parts[2] === 'open') { - const clonedActiveChats = Array.from(activeChats); - clonedActiveChats.push(new MessengerChat(friendId)); + setIsVisible(true); - dispatchFriendsState({ - type: FriendsActions.SET_ACTIVE_CHATS, - payload: { - chats: clonedActiveChats - } - }); - - existingChatIndex = clonedActiveChats.length - 1; + return; } - setSelectedChatIndex(existingChatIndex); - setIsVisible(true); - }, [ activeChats, dispatchFriendsState ]); + const [ threadIndex ] = getMessageThreadWithIndex(parseInt(parts[2])); - const getFriendFigure = useCallback((id: number) => - { - const friend = friends.find(f => f.id === id); + if(threadIndex === -1) return; - if(!friend) return null; - - return friend.figure; - }, [ friends ]); - - const selectChat = useCallback((index: number) => - { - const chat = activeChats[index]; - - if(!chat) return; - - dispatchFriendsState({ - type: FriendsActions.SET_CHAT_READ, - payload: { - numberValue: chat.friendId - } + BatchUpdates(() => + { + setActiveThreadIndex(threadIndex); + setIsVisible(true); }); - - setSelectedChatIndex(index); - }, [ activeChats, dispatchFriendsState ]); + }, [ getMessageThreadWithIndex ]); - const selectedChat = useMemo(() => - { - return activeChats[selectedChatIndex]; - }, [ activeChats, selectedChatIndex ]); - - const selectedChatFriend = useMemo(() => + const closeThread = useCallback((threadIndex: number) => { - if(!selectedChat) return null; + setHiddenThreadIndexes(prevValue => + { + const values = [ ...prevValue ]; - const friend = friends.find(f => f.id === selectedChat.friendId); + if(values.indexOf(threadIndex) === -1) values.push(threadIndex); - if(!friend) return null; - - return friend; - }, [ friends, selectedChat ]); + return values; + }); + }, []); useEffect(() => { @@ -121,112 +180,102 @@ export const FriendsMessengerView: FC<{}> = props => useEffect(() => { - if(!messagesBox || !messagesBox.current) return; - - messagesBox.current.scrollTop = messagesBox.current.scrollHeight; + if(!isVisible) return; - }, [ selectedChat ]); + if(activeThreadIndex === -1) setActiveThreadIndex(0); + }, [ isVisible, activeThreadIndex ]); - const followFriend = useCallback(() => + useEffect(() => { - SendMessageHook(new FollowFriendMessageComposer(selectedChatFriend.id)); - }, [ selectedChatFriend ]); + if(hiddenThreadIndexes.indexOf(activeThreadIndex) >= 0) setActiveThreadIndex(0); + }, [ activeThreadIndex, hiddenThreadIndexes ]); - const openProfile = useCallback(() => + useEffect(() => { - SendMessageHook(new UserProfileComposer(selectedChatFriend.id)); - }, [ selectedChatFriend ]); + if(!isVisible || (activeThreadIndex === -1)) return; - const sendMessage = useCallback(() => + const activeThread = messageThreads[activeThreadIndex]; + + if(activeThread.unread) + { + messagesBox.current.scrollTop = messagesBox.current.scrollHeight; + activeThread.setRead(); + setUpdateValue({}); + } + }, [ isVisible, messageThreads, activeThreadIndex ]); + + useEffect(() => { - if(message.length === 0) return; + if(!visibleThreads.length) + { + setIsVisible(false); - SendMessageHook(new SendMessageComposer(selectedChat.friendId, message)); + dispatchUiEvent(new FriendsMessengerIconEvent(FriendsMessengerIconEvent.UPDATE_ICON, FriendsMessengerIconEvent.HIDE_ICON)); - dispatchFriendsState({ - type: FriendsActions.ADD_CHAT_MESSAGE, - payload: { - chatMessage: new MessengerChatMessage(MessengerChatMessage.MESSAGE, 0, message, (new Date().getMilliseconds())), - numberValue: selectedChat.friendId, - boolValue: false + return; + } + + let isUnread = false; + + for(const thread of visibleThreads) + { + if(thread.unread) + { + isUnread = true; + + break; } - }); - setMessage(''); - }, [ selectedChat, message, dispatchFriendsState ]); + } - const onKeyDown = useCallback((event: KeyboardEvent) => - { - if(event.key !== 'Enter') return; - - sendMessage(); - }, [ sendMessage ]); + dispatchUiEvent(new FriendsMessengerIconEvent(FriendsMessengerIconEvent.UPDATE_ICON, isUnread ? FriendsMessengerIconEvent.UNREAD_ICON : FriendsMessengerIconEvent.SHOW_ICON)); + }, [ visibleThreads, updateValue ]); if(!isVisible) return null; - return ( - setIsVisible(false) } /> - -
- { activeChats && activeChats.map((chat, index) => + return ( + + setIsVisible(false) } /> + +
+ { visibleThreads && (visibleThreads.length > 0) && visibleThreads.map((thread, index) => { - return
selectChat(index) }> - { !chat.isRead && } - -
; + const messageThreadIndex = messageThreads.indexOf(thread); + + return ( +
setActiveThreadIndex(messageThreadIndex) }> + { thread.unread && } + +
+ ); }) } -
-
- { selectedChat && selectedChatFriend && <> -
{ LocalizeText('messenger.window.separator', ['FRIEND_NAME'], [ selectedChatFriend.name ]) }
+
+
+ { (activeThreadIndex >= 0) && + <> +
+ { LocalizeText('messenger.window.separator', [ 'FRIEND_NAME' ], [ messageThreads[activeThreadIndex].participant.name ]) } +
- -
- +
- { selectedChat.messageGroups.map((group, groupIndex) => - { - return
- { group.isSystem && <> - { group.messages.map((message, messageIndex) => - { - return
- { message.type === MessengerChatMessage.SECURITY_ALERT &&
- -
{ LocalizeText('messenger.moderationinfo') }
-
} -
- }) } - } - { !group.isSystem && <> - { group.userId !== 0 &&
- -
} -
- { group.messages.map((message, messageIndex) => - { - return
{ message.message }
- }) } -
- { group.userId === 0 &&
- -
} - } -
; - }) } +
- setMessage(e.target.value) } onKeyDown={ onKeyDown } /> + setMessageText(event.target.value) } onKeyDown={ onKeyDown } />
} -
-
); -}; + + + ); +} diff --git a/src/views/room/widgets/chat/message/ChatWidgetMessageView.scss b/src/views/room/widgets/chat/message/ChatWidgetMessageView.scss index 9bdbcb6b..9337ed85 100644 --- a/src/views/room/widgets/chat/message/ChatWidgetMessageView.scss +++ b/src/views/room/widgets/chat/message/ChatWidgetMessageView.scss @@ -696,7 +696,6 @@ justify-content: center; height: 100%; max-height: 24px; - image-rendering: -webkit-optimize-contrast; overflow: hidden; .user-image { @@ -707,8 +706,9 @@ height: 130px; background-repeat: no-repeat; background-position: center; - transform: scale(0.5) translateZ(0); + transform: scale(0.5); overflow: hidden; + image-rendering: -webkit-optimize-contrast; } } diff --git a/src/views/shared/avatar-image/AvatarImage.scss b/src/views/shared/avatar-image/AvatarImage.scss index f85ca9c4..a552dbb2 100644 --- a/src/views/shared/avatar-image/AvatarImage.scss +++ b/src/views/shared/avatar-image/AvatarImage.scss @@ -6,4 +6,10 @@ background-position-x: center; background-position-y: -8px !important; pointer-events: none; + image-rendering: pixelated; + + &.scale-0-5, + &.scale-0-75 { + image-rendering: -webkit-optimize-contrast; + } } diff --git a/src/views/shared/avatar-image/AvatarImageView.tsx b/src/views/shared/avatar-image/AvatarImageView.tsx index 5d2a2a33..d8e96979 100644 --- a/src/views/shared/avatar-image/AvatarImageView.tsx +++ b/src/views/shared/avatar-image/AvatarImageView.tsx @@ -1,5 +1,5 @@ import { AvatarScaleType, AvatarSetType } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useRef, useState } from 'react'; +import { FC, useEffect, useMemo, useRef, useState } from 'react'; import { GetAvatarRenderManager } from '../../../api'; import { AvatarImageViewProps } from './AvatarImageView.types'; @@ -10,6 +10,13 @@ export const AvatarImageView: FC = props => const [ randomValue, setRandomValue ] = useState(-1); const isDisposed = useRef(false); + const getScaleStyle = useMemo(() => + { + if(scale === .5) return '0-5'; + + return scale.toString(); + }, [ scale ]); + useEffect(() => { const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, gender, { @@ -50,5 +57,5 @@ export const AvatarImageView: FC = props => const url = `url('${ avatarUrl }')`; - return
; + return
; } diff --git a/src/views/shared/room-previewer/RoomPreviewerView.scss b/src/views/shared/room-previewer/RoomPreviewerView.scss index 55328299..e6192624 100644 --- a/src/views/shared/room-previewer/RoomPreviewerView.scss +++ b/src/views/shared/room-previewer/RoomPreviewerView.scss @@ -12,7 +12,6 @@ background-color: $light; background-repeat: no-repeat; background-position: center; - image-rendering: auto; &.border-0 { &::after { diff --git a/src/views/toolbar/ToolbarView.scss b/src/views/toolbar/ToolbarView.scss index 44abb043..57401e81 100644 --- a/src/views/toolbar/ToolbarView.scss +++ b/src/views/toolbar/ToolbarView.scss @@ -29,31 +29,28 @@ align-items: center; justify-content: center; cursor: pointer; - width: 50px; - margin: 0 1px; + //margin: 0 1px; position: relative; - .toolbar-avatar { - height: 50px; + &.item-avatar { + width: 50px; + height: 45px; + overflow: hidden; .avatar-image { margin-left: -5px; - margin-top: -30px; - } - - &:hover, &.active { - height: 53px; + margin-top: 25px; } } .icon, - .toolbar-avatar { + &.item-avatar { position: relative; - transition: transform .2s ease-out; + //transition: transform .2s ease-out; &:hover, &.active { - -webkit-transform: translate(0, -3px); - transform: translate(0, -3px); + -webkit-transform: translate(-1px, -1px); + transform: translate(-1px, -1px); filter: drop-shadow(2px 2px 0 rgba($black, 0.8)); } } @@ -68,7 +65,7 @@ .count { top: 0rem; - right: 5px; + right: 2px; font-size: 10px; } } diff --git a/src/views/toolbar/ToolbarView.tsx b/src/views/toolbar/ToolbarView.tsx index 3ab96937..4d10456b 100644 --- a/src/views/toolbar/ToolbarView.tsx +++ b/src/views/toolbar/ToolbarView.tsx @@ -1,7 +1,7 @@ import { Dispose, DropBounce, EaseOut, FigureUpdateEvent, JumpBy, Motions, NitroToolbarAnimateIconEvent, Queue, UserInfoDataParser, UserInfoEvent, UserProfileComposer, Wait } from '@nitrots/nitro-renderer'; import { FC, useCallback, useState } from 'react'; -import { GetRoomSession, GetRoomSessionManager, GetSessionDataManager, GoToDesktop } from '../../api'; -import { AvatarEditorEvent, CatalogEvent, FriendsEvent, InventoryEvent, NavigatorEvent, RoomWidgetCameraEvent } from '../../events'; +import { GetRoomSession, GetRoomSessionManager, GetSessionDataManager, GoToDesktop, OpenMessengerChat } from '../../api'; +import { AvatarEditorEvent, CatalogEvent, FriendsEvent, FriendsMessengerIconEvent, InventoryEvent, NavigatorEvent, RoomWidgetCameraEvent } from '../../events'; import { AchievementsUIEvent } from '../../events/achievements'; import { UnseenItemTrackerUpdateEvent } from '../../events/inventory/UnseenItemTrackerUpdateEvent'; import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent'; @@ -14,6 +14,10 @@ import { AvatarImageView } from '../shared/avatar-image/AvatarImageView'; import { ToolbarMeView } from './me/ToolbarMeView'; import { ToolbarViewItems, ToolbarViewProps } from './ToolbarView.types'; +const CHAT_ICON_HIDDEN: number = 0; +const CHAT_ICON_SHOWING: number = 1; +const CHAT_ICON_UNREAD: number = 2; + export const ToolbarView: FC = props => { const { isInRoom } = props; @@ -21,6 +25,7 @@ export const ToolbarView: FC = props => const [ userInfo, setUserInfo ] = useState(null); const [ userFigure, setUserFigure ] = useState(null); const [ isMeExpanded, setMeExpanded ] = useState(false); + const [ chatIconType, setChatIconType ] = useState(CHAT_ICON_HIDDEN); const [ unseenInventoryCount, setUnseenInventoryCount ] = useState(0); const unseenFriendListCount = 0; @@ -45,6 +50,13 @@ export const ToolbarView: FC = props => CreateMessageHook(FigureUpdateEvent, onUserFigureEvent); + const onFriendsMessengerIconEvent = useCallback((event: FriendsMessengerIconEvent) => + { + setChatIconType(event.iconType); + }, []); + + useUiEvent(FriendsMessengerIconEvent.UPDATE_ICON, onFriendsMessengerIconEvent); + const onUnseenItemTrackerUpdateEvent = useCallback((event: UnseenItemTrackerUpdateEvent) => { setUnseenInventoryCount(event.count); @@ -131,6 +143,9 @@ export const ToolbarView: FC = props => dispatchUiEvent(new UserSettingsUIEvent(UserSettingsUIEvent.TOGGLE_USER_SETTINGS)); setMeExpanded(false); return; + case ToolbarViewItems.FRIEND_CHAT_ITEM: + OpenMessengerChat(); + return; } }, []); @@ -148,20 +163,16 @@ export const ToolbarView: FC = props =>
-
-
-
-
setMeExpanded(!isMeExpanded) }> - -
+
+
+
setMeExpanded(!isMeExpanded) }> + + { (unseenAchievementsCount > 0) && +
{ unseenAchievementsCount }
}
- { (unseenAchievementsCount > 0) && ( -
{ unseenAchievementsCount }
) } -
-
{ isInRoom && (
- +
) } { !isInRoom && (
@@ -188,13 +199,20 @@ export const ToolbarView: FC = props =>
-
-
+
+
handleToolbarItemClick(ToolbarViewItems.FRIEND_LIST_ITEM) }> { (unseenFriendListCount > 0) && (
{ unseenFriendListCount }
) }
+ { ((chatIconType === CHAT_ICON_SHOWING) || (chatIconType === CHAT_ICON_UNREAD)) && +
handleToolbarItemClick(ToolbarViewItems.FRIEND_CHAT_ITEM) }> + { (chatIconType === CHAT_ICON_SHOWING) && } + { (chatIconType === CHAT_ICON_UNREAD) && } + { (unseenFriendListCount > 0) && +
{ unseenFriendListCount }
} +
}
diff --git a/src/views/toolbar/ToolbarView.types.ts b/src/views/toolbar/ToolbarView.types.ts index 0670bca7..48a376d1 100644 --- a/src/views/toolbar/ToolbarView.types.ts +++ b/src/views/toolbar/ToolbarView.types.ts @@ -9,6 +9,7 @@ export class ToolbarViewItems public static INVENTORY_ITEM: string = 'TVI_INVENTORY_ITEM'; public static CATALOG_ITEM: string = 'TVI_CATALOG_ITEM'; public static FRIEND_LIST_ITEM: string = 'TVI_FRIEND_LIST_ITEM'; + public static FRIEND_CHAT_ITEM: string = 'TVI_FRIEND_CHAT_ITEM'; public static CLOTHING_ITEM: string = 'TVI_CLOTHING_ITEM'; public static CAMERA_ITEM: string = 'TVI_CAMERA_ITEM'; public static MOD_TOOLS_ITEM: string = 'TVI_MOD_TOOLS_ITEM'; diff --git a/tsconfig.json b/tsconfig.json index df4dcf04..ac2a9fd7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,6 +24,6 @@ }, "include": [ "src", - "node_modules/@nitrots/nitro-renderer/**/*.ts", + "node_modules/@nitrots/nitro-renderer/src/**/*.ts", ] }