From 40856b8c9462c2a44274de70f257edf7ab64414e Mon Sep 17 00:00:00 2001 From: Bill Date: Sat, 2 Apr 2022 21:12:58 -0400 Subject: [PATCH] Updates --- src/api/friends/GetGroupChatData.ts | 2 + .../inventory}/FurnitureUtilities.ts | 18 +- .../common => api/inventory}/PetUtilities.ts | 6 +- .../inventory}/TradingUtilities.ts | 7 +- src/api/inventory/index.ts | 3 + src/components/friends/FriendsView.tsx | 2 +- .../friends/views/FriendBarView.tsx | 93 -------- .../views/friends-bar/FriendBarItemView.tsx | 59 +++++ .../views/friends-bar/FriendsBarView.tsx | 28 +++ .../friends-list/FriendsListGroupView.tsx | 105 --------- .../friends-list/FriendsListRequestView.tsx | 48 ---- .../views/friends-list/FriendsListView.tsx | 4 +- .../FriendsListGroupItemView.tsx | 85 +++++++ .../FriendsListGroupView.tsx | 23 ++ .../FriendsListRequestItemView.tsx | 25 +++ .../FriendsListRequestView.tsx | 29 +++ .../messenger/FriendsMessengerThreadGroup.tsx | 84 ------- .../messenger/FriendsMessengerThreadView.tsx | 84 ------- .../views/messenger/FriendsMessengerView.tsx | 48 ++-- .../FriendsMessengerThreadGroup.tsx | 72 ++++++ .../FriendsMessengerThreadView.tsx | 16 ++ .../furniture/InventoryFurnitureView.tsx | 15 +- .../views/furniture/InventoryTradeView.tsx | 3 +- .../FriendRequestDialogView.tsx | 30 +++ .../FriendRequestWidgetView.tsx | 32 +-- src/hooks/friends/useFriends.ts | 176 +++++++-------- src/hooks/friends/useMessenger.ts | 210 ++++++++++-------- src/hooks/inventory/common/index.ts | 3 - src/hooks/inventory/index.ts | 1 - src/hooks/inventory/useInventoryFurni.ts | 3 +- src/hooks/inventory/useInventoryPets.ts | 4 +- src/hooks/inventory/useInventoryTrade.ts | 3 +- 32 files changed, 631 insertions(+), 690 deletions(-) rename src/{hooks/inventory/common => api/inventory}/FurnitureUtilities.ts (89%) rename src/{hooks/inventory/common => api/inventory}/PetUtilities.ts (91%) rename src/{hooks/inventory/common => api/inventory}/TradingUtilities.ts (87%) delete mode 100644 src/components/friends/views/FriendBarView.tsx create mode 100644 src/components/friends/views/friends-bar/FriendBarItemView.tsx create mode 100644 src/components/friends/views/friends-bar/FriendsBarView.tsx delete mode 100644 src/components/friends/views/friends-list/FriendsListGroupView.tsx delete mode 100644 src/components/friends/views/friends-list/FriendsListRequestView.tsx create mode 100644 src/components/friends/views/friends-list/friends-list-group/FriendsListGroupItemView.tsx create mode 100644 src/components/friends/views/friends-list/friends-list-group/FriendsListGroupView.tsx create mode 100644 src/components/friends/views/friends-list/friends-list-request/FriendsListRequestItemView.tsx create mode 100644 src/components/friends/views/friends-list/friends-list-request/FriendsListRequestView.tsx delete mode 100644 src/components/friends/views/messenger/FriendsMessengerThreadGroup.tsx delete mode 100644 src/components/friends/views/messenger/FriendsMessengerThreadView.tsx create mode 100644 src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadGroup.tsx create mode 100644 src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadView.tsx create mode 100644 src/components/room/widgets/friend-request/FriendRequestDialogView.tsx delete mode 100644 src/hooks/inventory/common/index.ts diff --git a/src/api/friends/GetGroupChatData.ts b/src/api/friends/GetGroupChatData.ts index 4e8a0243..75df9629 100644 --- a/src/api/friends/GetGroupChatData.ts +++ b/src/api/friends/GetGroupChatData.ts @@ -2,6 +2,8 @@ import { IGroupChatData } from './IGroupChatData'; export const GetGroupChatData = (extraData: string) => { + if(!extraData || !extraData.length) return null; + const splitData = extraData.split('/'); const username = splitData[0]; const figure = splitData[1]; diff --git a/src/hooks/inventory/common/FurnitureUtilities.ts b/src/api/inventory/FurnitureUtilities.ts similarity index 89% rename from src/hooks/inventory/common/FurnitureUtilities.ts rename to src/api/inventory/FurnitureUtilities.ts index f4a16212..741f1ea1 100644 --- a/src/hooks/inventory/common/FurnitureUtilities.ts +++ b/src/api/inventory/FurnitureUtilities.ts @@ -1,18 +1,8 @@ import { FurnitureListItemParser, IObjectData } from '@nitrots/nitro-renderer'; -import { DispatchUiEvent } from '../..'; -import { FurniCategory, FurnitureItem, GetRoomEngine, GroupItem } from '../../../api'; -import { CatalogPostMarketplaceOfferEvent } from '../../../events'; - -export const attemptPlaceMarketplaceOffer = (groupItem: GroupItem) => -{ - const item = groupItem.getLastItem(); - - if(!item) return false; - - if(!item.sellable) return false; - - DispatchUiEvent(new CatalogPostMarketplaceOfferEvent(item)); -} +import { GetRoomEngine } from '../nitro'; +import { FurniCategory } from './FurniCategory'; +import { FurnitureItem } from './FurnitureItem'; +import { GroupItem } from './GroupItem'; export const createGroupItem = (type: number, category: number, stuffData: IObjectData, extra: number = NaN) => new GroupItem(type, category, GetRoomEngine(), stuffData, extra); diff --git a/src/hooks/inventory/common/PetUtilities.ts b/src/api/inventory/PetUtilities.ts similarity index 91% rename from src/hooks/inventory/common/PetUtilities.ts rename to src/api/inventory/PetUtilities.ts index 3c023c2b..871eb538 100644 --- a/src/hooks/inventory/common/PetUtilities.ts +++ b/src/api/inventory/PetUtilities.ts @@ -1,6 +1,8 @@ import { PetData } from '@nitrots/nitro-renderer'; -import { cancelRoomObjectPlacement, CreateLinkEvent, getPlacingItemId, UnseenItemCategory } from '../../../api'; -import { IPetItem } from '../../../api/inventory/IPetItem'; +import { CreateLinkEvent } from '../nitro'; +import { cancelRoomObjectPlacement, getPlacingItemId } from './InventoryUtilities'; +import { IPetItem } from './IPetItem'; +import { UnseenItemCategory } from './unseen'; export const getAllPetIds = (petItems: IPetItem[]) => petItems.map(item => item.petData.id); diff --git a/src/hooks/inventory/common/TradingUtilities.ts b/src/api/inventory/TradingUtilities.ts similarity index 87% rename from src/hooks/inventory/common/TradingUtilities.ts rename to src/api/inventory/TradingUtilities.ts index e744f2a7..28ca8c88 100644 --- a/src/hooks/inventory/common/TradingUtilities.ts +++ b/src/api/inventory/TradingUtilities.ts @@ -1,6 +1,9 @@ import { AdvancedMap, IObjectData, ItemDataStructure, StringDataType } from '@nitrots/nitro-renderer'; -import { createGroupItem } from '.'; -import { FurniCategory, FurnitureItem, GetSessionDataManager, GroupItem } from '../../../api'; +import { GetSessionDataManager } from '../nitro'; +import { FurniCategory } from './FurniCategory'; +import { FurnitureItem } from './FurnitureItem'; +import { createGroupItem } from './FurnitureUtilities'; +import { GroupItem } from './GroupItem'; const isExternalImage = (spriteId: number) => GetSessionDataManager().getWallItemData(spriteId)?.isExternalImage || false; diff --git a/src/api/inventory/index.ts b/src/api/inventory/index.ts index 1eca74d0..de840525 100644 --- a/src/api/inventory/index.ts +++ b/src/api/inventory/index.ts @@ -1,12 +1,15 @@ export * from './FurniCategory'; export * from './FurnitureItem'; +export * from './FurnitureUtilities'; export * from './GroupItem'; export * from './IBotItem'; export * from './IFurnitureItem'; export * from './InventoryUtilities'; export * from './IPetItem'; +export * from './PetUtilities'; export * from './TradeState'; export * from './TradeUserData'; export * from './TradingNotificationMessage'; export * from './TradingNotificationType'; +export * from './TradingUtilities'; export * from './unseen'; diff --git a/src/components/friends/FriendsView.tsx b/src/components/friends/FriendsView.tsx index 5a9d271d..6d639759 100644 --- a/src/components/friends/FriendsView.tsx +++ b/src/components/friends/FriendsView.tsx @@ -1,7 +1,7 @@ import { FC } from 'react'; import { createPortal } from 'react-dom'; import { useFriends } from '../../hooks'; -import { FriendBarView } from './views/FriendBarView'; +import { FriendBarView } from './views/friends-bar/FriendsBarView'; import { FriendsListView } from './views/friends-list/FriendsListView'; import { FriendsMessengerView } from './views/messenger/FriendsMessengerView'; diff --git a/src/components/friends/views/FriendBarView.tsx b/src/components/friends/views/FriendBarView.tsx deleted file mode 100644 index a9978965..00000000 --- a/src/components/friends/views/FriendBarView.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { MouseEventType } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useRef, useState } from 'react'; -import { GetUserProfile, LocalizeText, MessengerFriend, OpenMessengerChat } from '../../../api'; -import { Base, Button, Flex, LayoutAvatarImageView, LayoutBadgeImageView } from '../../../common'; -import { useFriends } from '../../../hooks'; - -interface FriendBarViewProps -{ - onlineFriends: MessengerFriend[]; -} - -export const FriendBarView: FC = props => -{ - const { onlineFriends = null } = props; - const [ indexOffset, setIndexOffset ] = useState(0); - const [ maxDisplayCount, setMaxDisplayCount ] = useState(3); - const { followFriend = null } = useFriends(); - - const FriendBarItemView: FC<{ friend: MessengerFriend }> = props => - { - const { friend = null } = props; - const [ isVisible, setVisible ] = useState(false); - const elementRef = useRef(); - - useEffect(() => - { - const onClick = (event: MouseEvent) => - { - const element = elementRef.current; - - if(!element) return; - - if((event.target !== element) && !element.contains((event.target as Node))) - { - setVisible(false); - } - } - - document.addEventListener(MouseEventType.MOUSE_CLICK, onClick); - - return () => - { - document.removeEventListener(MouseEventType.MOUSE_CLICK, onClick); - } - }, []); - - if(!friend) - { - return ( -
-
-
{ LocalizeText('friend.bar.find.title') }
-
- ); - } - - return ( -
setVisible(prevValue => !prevValue) }> -
0 ? 'avatar': 'group'}`}> - { friend.id > 0 && } - { friend.id <= 0 && } -
-
{ friend.name }
- { isVisible && -
- OpenMessengerChat(friend.id) } /> - { friend.followingAllowed && - followFriend(friend) } /> } - GetUserProfile(friend.id) } /> -
} -
- ); - } - - const canDecreaseIndex = () => (indexOffset === 0) ? false : true; - const canIncreaseIndex = () => ((onlineFriends.length <= maxDisplayCount) || (indexOffset === (onlineFriends.length - 1))) ? false : true; - - return ( - - - { Array.from(Array(maxDisplayCount), (e, i) => - { - return ; - }) } - - - ); -} diff --git a/src/components/friends/views/friends-bar/FriendBarItemView.tsx b/src/components/friends/views/friends-bar/FriendBarItemView.tsx new file mode 100644 index 00000000..30f7a31e --- /dev/null +++ b/src/components/friends/views/friends-bar/FriendBarItemView.tsx @@ -0,0 +1,59 @@ +import { MouseEventType } from '@nitrots/nitro-renderer'; +import { FC, useEffect, useRef, useState } from 'react'; +import { GetUserProfile, LocalizeText, MessengerFriend, OpenMessengerChat } from '../../../../api'; +import { Base, LayoutAvatarImageView, LayoutBadgeImageView } from '../../../../common'; +import { useFriends } from '../../../../hooks'; + +export const FriendBarItemView: FC<{ friend: MessengerFriend }> = props => +{ + const { friend = null } = props; + const [ isVisible, setVisible ] = useState(false); + const { followFriend = null } = useFriends(); + const elementRef = useRef(); + + useEffect(() => + { + const onClick = (event: MouseEvent) => + { + const element = elementRef.current; + + if(!element) return; + + if((event.target !== element) && !element.contains((event.target as Node))) + { + setVisible(false); + } + } + + document.addEventListener(MouseEventType.MOUSE_CLICK, onClick); + + return () => document.removeEventListener(MouseEventType.MOUSE_CLICK, onClick); + }, []); + + if(!friend) + { + return ( +
+
+
{ LocalizeText('friend.bar.find.title') }
+
+ ); + } + + return ( +
setVisible(prevValue => !prevValue) }> +
0 ? 'avatar': 'group'}`}> + { (friend.id > 0) && } + { (friend.id <= 0) && } +
+
{ friend.name }
+ { isVisible && +
+ OpenMessengerChat(friend.id) } /> + { friend.followingAllowed && + followFriend(friend) } /> } + GetUserProfile(friend.id) } /> +
} +
+ ); +} diff --git a/src/components/friends/views/friends-bar/FriendsBarView.tsx b/src/components/friends/views/friends-bar/FriendsBarView.tsx new file mode 100644 index 00000000..8ca8eb57 --- /dev/null +++ b/src/components/friends/views/friends-bar/FriendsBarView.tsx @@ -0,0 +1,28 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { FC, useState } from 'react'; +import { MessengerFriend } from '../../../../api'; +import { Button, Flex } from '../../../../common'; +import { FriendBarItemView } from './FriendBarItemView'; + +const MAX_DISPLAY_COUNT = 3; + +export const FriendBarView: FC<{ onlineFriends: MessengerFriend[] }> = props => +{ + const { onlineFriends = null } = props; + const [ indexOffset, setIndexOffset ] = useState(0); + + const canDecreaseIndex = () => (indexOffset === 0) ? false : true; + const canIncreaseIndex = () => ((onlineFriends.length <= MAX_DISPLAY_COUNT) || (indexOffset === (onlineFriends.length - 1))) ? false : true; + + return ( + + + { Array.from(Array(MAX_DISPLAY_COUNT), (e, i) => ) } + + + ); +} diff --git a/src/components/friends/views/friends-list/FriendsListGroupView.tsx b/src/components/friends/views/friends-list/FriendsListGroupView.tsx deleted file mode 100644 index 55828a31..00000000 --- a/src/components/friends/views/friends-list/FriendsListGroupView.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import { FC, MouseEvent, useState } from 'react'; -import { LocalizeText, MessengerFriend, OpenMessengerChat } from '../../../../api'; -import { Base, Flex, NitroCardAccordionItemView, UserProfileIconView } from '../../../../common'; -import { useFriends } from '../../../../hooks'; - -interface FriendsListGroupViewProps -{ - list: MessengerFriend[]; - selectedFriendsIds: number[]; - selectFriend: (userId: number) => void; -} - -export const FriendsListGroupView: FC = props => -{ - const { list = null, selectedFriendsIds = null, selectFriend = null } = props; - const { followFriend = null, updateRelationship = null } = useFriends(); - - if(!list || !list.length) return null; - - const FriendsListGroupItemView: FC<{ friend: MessengerFriend, selected: boolean }> = props => - { - const { friend = null, selected = false } = props; - const [ isRelationshipOpen, setIsRelationshipOpen ] = useState(false); - - const clickFollowFriend = (event: MouseEvent) => - { - event.stopPropagation(); - - followFriend(friend); - } - - const openMessengerChat = (event: MouseEvent) => - { - event.stopPropagation(); - - OpenMessengerChat(friend.id); - } - - const openRelationship = (event: MouseEvent) => - { - event.stopPropagation(); - - setIsRelationshipOpen(true); - } - - const clickUpdateRelationship = (event: MouseEvent, type: number) => - { - event.stopPropagation(); - - updateRelationship(friend, type); - - setIsRelationshipOpen(false); - } - - const getCurrentRelationshipName = () => - { - if(!friend) return 'none'; - - switch(friend.relationshipStatus) - { - case MessengerFriend.RELATIONSHIP_HEART: return 'heart'; - case MessengerFriend.RELATIONSHIP_SMILE: return 'smile'; - case MessengerFriend.RELATIONSHIP_BOBBA: return 'bobba'; - default: return 'none'; - } - } - - if(!friend) return null; - - return ( - selectFriend(friend.id) }> - - event.stopPropagation() }> - - -
{ friend.name }
-
- - { !isRelationshipOpen && - <> - { friend.followingAllowed && - } - { friend.online && - } - { (friend.id > 0) && - } - } - { isRelationshipOpen && - <> - clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_HEART) } /> - clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_SMILE) } /> - clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_BOBBA) } /> - clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_NONE) } /> - } - -
- ); - } - - return ( - <> - { list.map((item, index) => ) } - - ); -} diff --git a/src/components/friends/views/friends-list/FriendsListRequestView.tsx b/src/components/friends/views/friends-list/FriendsListRequestView.tsx deleted file mode 100644 index bdbb414d..00000000 --- a/src/components/friends/views/friends-list/FriendsListRequestView.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText, MessengerRequest } from '../../../../api'; -import { Base, Button, Column, Flex, NitroCardAccordionItemView, NitroCardAccordionSetView, NitroCardAccordionSetViewProps, UserProfileIconView } from '../../../../common'; -import { useFriends } from '../../../../hooks'; - -export const FriendsListRequestView: FC = props => -{ - const { children = null, ...rest } = props; - const { requests = [], requestResponse = null } = useFriends(); - - if(!requests.length) return null; - - const FriendsListRequestItemView: FC<{ request: MessengerRequest }> = props => - { - const { request = null } = props; - - if(!request) return null; - - return ( - - - -
{ request.name }
-
- - requestResponse(request.id, true) } /> - requestResponse(request.id, false) } /> - -
- ); - } - - return ( - - - - { requests.map((request, index) => ) } - - - - - - { children } - - ); -} diff --git a/src/components/friends/views/friends-list/FriendsListView.tsx b/src/components/friends/views/friends-list/FriendsListView.tsx index d69255a2..8dbb9c3e 100644 --- a/src/components/friends/views/friends-list/FriendsListView.tsx +++ b/src/components/friends/views/friends-list/FriendsListView.tsx @@ -3,9 +3,9 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { AddEventLinkTracker, LocalizeText, MessengerFriend, RemoveLinkEventTracker, SendMessageComposer } from '../../../../api'; import { Button, Flex, NitroCardAccordionSetView, NitroCardAccordionView, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common'; import { useFriends } from '../../../../hooks'; -import { FriendsListGroupView } from './FriendsListGroupView'; +import { FriendsListGroupView } from './friends-list-group/FriendsListGroupView'; +import { FriendsListRequestView } from './friends-list-request/FriendsListRequestView'; import { FriendsRemoveConfirmationView } from './FriendsListRemoveConfirmationView'; -import { FriendsListRequestView } from './FriendsListRequestView'; import { FriendsRoomInviteView } from './FriendsListRoomInviteView'; import { FriendsSearchView } from './FriendsListSearchView'; diff --git a/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupItemView.tsx b/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupItemView.tsx new file mode 100644 index 00000000..03cd7e98 --- /dev/null +++ b/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupItemView.tsx @@ -0,0 +1,85 @@ +import { FC, MouseEvent, useState } from 'react'; +import { LocalizeText, MessengerFriend, OpenMessengerChat } from '../../../../../api'; +import { Base, Flex, NitroCardAccordionItemView, UserProfileIconView } from '../../../../../common'; +import { useFriends } from '../../../../../hooks'; + +export const FriendsListGroupItemView: FC<{ friend: MessengerFriend, selected: boolean, selectFriend: (userId: number) => void }> = props => +{ + const { friend = null, selected = false, selectFriend = null } = props; + const [ isRelationshipOpen, setIsRelationshipOpen ] = useState(false); + const { followFriend = null, updateRelationship = null } = useFriends(); + + const clickFollowFriend = (event: MouseEvent) => + { + event.stopPropagation(); + + followFriend(friend); + } + + const openMessengerChat = (event: MouseEvent) => + { + event.stopPropagation(); + + OpenMessengerChat(friend.id); + } + + const openRelationship = (event: MouseEvent) => + { + event.stopPropagation(); + + setIsRelationshipOpen(true); + } + + const clickUpdateRelationship = (event: MouseEvent, type: number) => + { + event.stopPropagation(); + + updateRelationship(friend, type); + + setIsRelationshipOpen(false); + } + + const getCurrentRelationshipName = () => + { + if(!friend) return 'none'; + + switch(friend.relationshipStatus) + { + case MessengerFriend.RELATIONSHIP_HEART: return 'heart'; + case MessengerFriend.RELATIONSHIP_SMILE: return 'smile'; + case MessengerFriend.RELATIONSHIP_BOBBA: return 'bobba'; + default: return 'none'; + } + } + + if(!friend) return null; + + return ( + selectFriend(friend.id) }> + + event.stopPropagation() }> + + +
{ friend.name }
+
+ + { !isRelationshipOpen && + <> + { friend.followingAllowed && + } + { friend.online && + } + { (friend.id > 0) && + } + } + { isRelationshipOpen && + <> + clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_HEART) } /> + clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_SMILE) } /> + clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_BOBBA) } /> + clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_NONE) } /> + } + +
+ ); +} diff --git a/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupView.tsx b/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupView.tsx new file mode 100644 index 00000000..c593003a --- /dev/null +++ b/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupView.tsx @@ -0,0 +1,23 @@ +import { FC } from 'react'; +import { MessengerFriend } from '../../../../../api'; +import { FriendsListGroupItemView } from './FriendsListGroupItemView'; + +interface FriendsListGroupViewProps +{ + list: MessengerFriend[]; + selectedFriendsIds: number[]; + selectFriend: (userId: number) => void; +} + +export const FriendsListGroupView: FC = props => +{ + const { list = null, selectedFriendsIds = null, selectFriend = null } = props; + + if(!list || !list.length) return null; + + return ( + <> + { list.map((item, index) => = 0) } selectFriend={ selectFriend } />) } + + ); +} diff --git a/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestItemView.tsx b/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestItemView.tsx new file mode 100644 index 00000000..de5d3a3b --- /dev/null +++ b/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestItemView.tsx @@ -0,0 +1,25 @@ +import { FC } from 'react'; +import { MessengerRequest } from '../../../../../api'; +import { Base, Flex, NitroCardAccordionItemView, UserProfileIconView } from '../../../../../common'; +import { useFriends } from '../../../../../hooks'; + +export const FriendsListRequestItemView: FC<{ request: MessengerRequest }> = props => +{ + const { request = null } = props; + const { requestResponse = null } = useFriends(); + + if(!request) return null; + + return ( + + + +
{ request.name }
+
+ + requestResponse(request.id, true) } /> + requestResponse(request.id, false) } /> + +
+ ); +} diff --git a/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestView.tsx b/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestView.tsx new file mode 100644 index 00000000..5f6e9918 --- /dev/null +++ b/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestView.tsx @@ -0,0 +1,29 @@ +import { FC } from 'react'; +import { LocalizeText } from '../../../../../api'; +import { Button, Column, Flex, NitroCardAccordionSetView, NitroCardAccordionSetViewProps } from '../../../../../common'; +import { useFriends } from '../../../../../hooks'; +import { FriendsListRequestItemView } from './FriendsListRequestItemView'; + +export const FriendsListRequestView: FC = props => +{ + const { children = null, ...rest } = props; + const { requests = [], requestResponse = null } = useFriends(); + + if(!requests.length) return null; + + return ( + + + + { requests.map((request, index) => ) } + + + + + + { children } + + ); +} diff --git a/src/components/friends/views/messenger/FriendsMessengerThreadGroup.tsx b/src/components/friends/views/messenger/FriendsMessengerThreadGroup.tsx deleted file mode 100644 index 37343c96..00000000 --- a/src/components/friends/views/messenger/FriendsMessengerThreadGroup.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { FC, useMemo } from 'react'; -import { GetSessionDataManager, LocalizeText } from '../../../../api'; -import { Base, Flex, LayoutAvatarImageView } from '../../../../common'; -import { GroupType } from '../../common/GroupType'; -import { MessengerThread } from '../../common/MessengerThread'; -import { MessengerThreadChat } from '../../common/MessengerThreadChat'; -import { MessengerThreadChatGroup } from '../../common/MessengerThreadChatGroup'; -import { getGroupChatData } from '../../common/Utils'; - -interface FriendsMessengerThreadGroupProps -{ - thread: MessengerThread; - group: MessengerThreadChatGroup; -} - -export const FriendsMessengerThreadGroup: FC = props => -{ - const { thread = null, group = null } = props; - - const isOwnChat = useMemo(() => - { - if(!thread || !group) return false; - - if(group.type === GroupType.PRIVATE_CHAT && (group.userId === GetSessionDataManager().userId)) return true; - - if( (group.type === GroupType.GROUP_CHAT) && (group.chats.length && getGroupChatData(group.chats[0].extraData).userId === GetSessionDataManager().userId)) return true; - - return false; - }, [ group, thread ]); - - if(!thread || !group) return null; - - if(!group.userId) - { - return ( - <> - { group.chats.map((chat, index) => - { - return ( -
- - { chat.type === MessengerThreadChat.SECURITY_NOTIFICATION && - - - { chat.message } - } - { chat.type === MessengerThreadChat.ROOM_INVITE && - - - {(LocalizeText('messenger.invitation') + ' ') }{ chat.message } - } - -
- ); - }) } - - ); - } - - return ( - - - { (group.type === GroupType.PRIVATE_CHAT && !isOwnChat) && - - } - { (group.type === GroupType.GROUP_CHAT && !isOwnChat) && - - } - - - - { (isOwnChat) && GetSessionDataManager().userName } - { (!isOwnChat) && ((group.type === GroupType.GROUP_CHAT) ? getGroupChatData(group.chats[0].extraData).username : thread.participant.name) - } - - { group.chats.map((chat, index) =>{ chat.message }) } - - { (isOwnChat) && - - - } - - ); -} diff --git a/src/components/friends/views/messenger/FriendsMessengerThreadView.tsx b/src/components/friends/views/messenger/FriendsMessengerThreadView.tsx deleted file mode 100644 index 66c96a7c..00000000 --- a/src/components/friends/views/messenger/FriendsMessengerThreadView.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { FC, useMemo } from 'react'; -import { GetGroupChatData, GetSessionDataManager, GroupType, LocalizeText, MessengerThread, MessengerThreadChat, MessengerThreadChatGroup } from '../../../../api'; -import { Base, Flex, LayoutAvatarImageView } from '../../../../common'; - -export const FriendsMessengerThreadView: FC<{ thread: MessengerThread }> = props => -{ - const { thread = null } = props; - - const FriendsMessengerThreadGroup: FC<{ thread: MessengerThread, group: MessengerThreadChatGroup }> = props => - { - const { thread = null, group = null, ...rest } = props; - - const isOwnChat = useMemo(() => - { - if(!thread || !group) return false; - - if(group.type === GroupType.PRIVATE_CHAT && (group.userId === GetSessionDataManager().userId)) return true; - - if( (group.type === GroupType.GROUP_CHAT) && (group.chats.length && GetGroupChatData(group.chats[0].extraData).userId === GetSessionDataManager().userId)) return true; - - return false; - }, [ group, thread ]); - - if(!thread || !group) return null; - - if(!group.userId) - { - return ( - <> - { group.chats.map((chat, index) => - { - return ( - - - { (chat.type === MessengerThreadChat.SECURITY_NOTIFICATION) && - - - { chat.message } - } - { (chat.type === MessengerThreadChat.ROOM_INVITE) && - - - { `${ LocalizeText('messenger.invitation') } ${ chat.message }` } - } - - - ); - }) } - - ); - } - - return ( - - - { (group.type === GroupType.PRIVATE_CHAT && !isOwnChat) && - - } - { (group.type === GroupType.GROUP_CHAT && !isOwnChat) && - - } - - - - { (isOwnChat) && GetSessionDataManager().userName } - { (!isOwnChat) && ((group.type === GroupType.GROUP_CHAT) ? GetGroupChatData(group.chats[0].extraData).username : thread.participant.name) - } - - { group.chats.map((chat, index) =>{ chat.message }) } - - { (isOwnChat) && - - - } - - ); - } - - return ( - <> - { (thread.groups.length > 0) && thread.groups.map((group, index) => ) } - - ); -} diff --git a/src/components/friends/views/messenger/FriendsMessengerView.tsx b/src/components/friends/views/messenger/FriendsMessengerView.tsx index 13364bcc..28bc8880 100644 --- a/src/components/friends/views/messenger/FriendsMessengerView.tsx +++ b/src/components/friends/views/messenger/FriendsMessengerView.tsx @@ -4,14 +4,14 @@ import { FC, KeyboardEvent, useEffect, useRef, useState } from 'react'; import { AddEventLinkTracker, GetUserProfile, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../../../api'; import { Base, Button, ButtonGroup, Column, Flex, Grid, LayoutAvatarImageView, LayoutBadgeImageView, LayoutGridItem, LayoutItemCountView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; import { useMessenger } from '../../../../hooks'; -import { FriendsMessengerThreadView } from './FriendsMessengerThreadView'; +import { FriendsMessengerThreadView } from './messenger-thread/FriendsMessengerThreadView'; export const FriendsMessengerView: FC<{}> = props => { const [ isVisible, setIsVisible ] = useState(false); const [ lastThreadId, setLastThreadId ] = useState(-1); const [ messageText, setMessageText ] = useState(''); - const { visibleThreads = [], activeThread = null, getMessageThread = null, sendMessage = null, setActiveThread = null, closeThread = null } = useMessenger(); + const { visibleThreads = [], activeThread = null, getMessageThread = null, sendMessage = null, setActiveThreadId = null, closeThread = null } = useMessenger(); const messagesBox = useRef(); const followFriend = () => (activeThread && activeThread.participant && SendMessageComposer(new FollowFriendMessageComposer(activeThread.participant.id))); @@ -54,7 +54,7 @@ export const FriendsMessengerView: FC<{}> = props => if(!thread) return; - setActiveThread(thread); + setActiveThreadId(thread.threadId); setIsVisible(true); } } @@ -65,14 +65,7 @@ export const FriendsMessengerView: FC<{}> = props => AddEventLinkTracker(linkTracker); return () => RemoveLinkEventTracker(linkTracker); - }, [ getMessageThread, setActiveThread ]); - - // useEffect(() => - // { - // if(!isVisible || activeThread || !visibleThreads || !visibleThreads.length) return; - - // setActiveThread(visibleThreads[0]); - // }, [ isVisible, visibleThreads, activeThread, setActiveThread ]); + }, [ getMessageThread, setActiveThreadId ]); useEffect(() => { @@ -83,23 +76,26 @@ export const FriendsMessengerView: FC<{}> = props => useEffect(() => { - if(!activeThread) return; - - return () => + if(isVisible && !activeThread) + { + if(lastThreadId > 0) + { + setActiveThreadId(lastThreadId); + } + else + { + if(visibleThreads.length > 0) setActiveThreadId(visibleThreads[0].threadId); + } + + return; + } + + if(!isVisible && activeThread) { - console.log('set last thread id', activeThread.threadId); setLastThreadId(activeThread.threadId); + setActiveThreadId(-1); } - }, [ activeThread ]); - - useEffect(() => - { - return () => - { - console.log('clear thread') - setActiveThread(null); - } - }, [ setActiveThread ]); + }, [ isVisible, activeThread, lastThreadId, visibleThreads, setActiveThreadId ]); if(!isVisible) return null; @@ -114,7 +110,7 @@ export const FriendsMessengerView: FC<{}> = props => { visibleThreads && (visibleThreads.length > 0) && visibleThreads.map(thread => { return ( - setActiveThread(thread) }> + setActiveThreadId(thread.threadId) }> { thread.unread && } diff --git a/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadGroup.tsx b/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadGroup.tsx new file mode 100644 index 00000000..2ab468ef --- /dev/null +++ b/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadGroup.tsx @@ -0,0 +1,72 @@ +import { FC, useMemo } from 'react'; +import { GetGroupChatData, GetSessionDataManager, GroupType, LocalizeText, 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 isOwnChat = useMemo(() => + { + if(!thread || !group) return false; + + if((group.type === GroupType.PRIVATE_CHAT) && (group.userId === GetSessionDataManager().userId)) return true; + + if(groupChatData && group.chats.length && (groupChatData.userId === GetSessionDataManager().userId)) return true; + + return false; + }, [ thread, group, groupChatData ]); + + if(!thread || !group) return null; + + if(!group.userId) + { + return ( + <> + { group.chats.map((chat, index) => + { + return ( + + + { (chat.type === MessengerThreadChat.SECURITY_NOTIFICATION) && + + + { chat.message } + } + { (chat.type === MessengerThreadChat.ROOM_INVITE) && + + + { (LocalizeText('messenger.invitation') + ' ') }{ chat.message } + } + + + ); + }) } + + ); + } + + return ( + + + { ((group.type === GroupType.PRIVATE_CHAT) && !isOwnChat) && + } + { (groupChatData && !isOwnChat) && + } + + + + { isOwnChat && GetSessionDataManager().userName } + { !isOwnChat && (groupChatData ? groupChatData.username : thread.participant.name) } + + { group.chats.map((chat, index) => { chat.message }) } + + { isOwnChat && + + + } + + ); +} diff --git a/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadView.tsx b/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadView.tsx new file mode 100644 index 00000000..962a6682 --- /dev/null +++ b/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadView.tsx @@ -0,0 +1,16 @@ +import { FC } from 'react'; +import { MessengerThread } from '../../../../../api'; +import { FriendsMessengerThreadGroup } from './FriendsMessengerThreadGroup'; + +export const FriendsMessengerThreadView: FC<{ thread: MessengerThread }> = props => +{ + const { thread = null } = props; + + thread.setRead(); + + return ( + <> + { (thread.groups.length > 0) && thread.groups.map((group, index) => ) } + + ); +} diff --git a/src/components/inventory/views/furniture/InventoryFurnitureView.tsx b/src/components/inventory/views/furniture/InventoryFurnitureView.tsx index 01d364c5..0f143b7a 100644 --- a/src/components/inventory/views/furniture/InventoryFurnitureView.tsx +++ b/src/components/inventory/views/furniture/InventoryFurnitureView.tsx @@ -2,8 +2,8 @@ import { IRoomSession, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitr import { FC, useEffect, useState } from 'react'; import { attemptItemPlacement, FurniCategory, GetRoomEngine, GetSessionDataManager, GroupItem, LocalizeText, UnseenItemCategory } from '../../../../api'; import { AutoGrid, Button, Column, Grid, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, LayoutRoomPreviewerView, Text } from '../../../../common'; -import { useInventoryFurni, useInventoryUnseenTracker } from '../../../../hooks'; -import { attemptPlaceMarketplaceOffer } from '../../../../hooks/inventory/common'; +import { CatalogPostMarketplaceOfferEvent } from '../../../../events'; +import { DispatchUiEvent, useInventoryFurni, useInventoryUnseenTracker } from '../../../../hooks'; import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView'; import { InventoryFurnitureItemView } from './InventoryFurnitureItemView'; import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView'; @@ -14,6 +14,17 @@ interface InventoryFurnitureViewProps roomPreviewer: RoomPreviewer; } +const attemptPlaceMarketplaceOffer = (groupItem: GroupItem) => +{ + const item = groupItem.getLastItem(); + + if(!item) return false; + + if(!item.sellable) return false; + + DispatchUiEvent(new CatalogPostMarketplaceOfferEvent(item)); +} + export const InventoryFurnitureView: FC = props => { const { roomSession = null, roomPreviewer = null } = props; diff --git a/src/components/inventory/views/furniture/InventoryTradeView.tsx b/src/components/inventory/views/furniture/InventoryTradeView.tsx index f9ce0e62..264171a9 100644 --- a/src/components/inventory/views/furniture/InventoryTradeView.tsx +++ b/src/components/inventory/views/furniture/InventoryTradeView.tsx @@ -1,10 +1,9 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IObjectData, TradingListAddItemComposer, TradingListAddItemsComposer } from '@nitrots/nitro-renderer'; import { FC, useEffect, useState } from 'react'; -import { FurniCategory, GroupItem, IFurnitureItem, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TradeState } from '../../../../api'; +import { FurniCategory, getGuildFurniType, GroupItem, IFurnitureItem, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TradeState } from '../../../../api'; import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, Text } from '../../../../common'; import { useInventoryTrade } from '../../../../hooks'; -import { getGuildFurniType } from '../../../../hooks/inventory/common/TradingUtilities'; import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView'; interface InventoryTradeViewProps diff --git a/src/components/room/widgets/friend-request/FriendRequestDialogView.tsx b/src/components/room/widgets/friend-request/FriendRequestDialogView.tsx new file mode 100644 index 00000000..f22b2139 --- /dev/null +++ b/src/components/room/widgets/friend-request/FriendRequestDialogView.tsx @@ -0,0 +1,30 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { RoomObjectCategory } from '@nitrots/nitro-renderer'; +import { FC } from 'react'; +import { LocalizeText, MessengerRequest } from '../../../../api'; +import { Base, Button, Column, Flex, Text } from '../../../../common'; +import { useFriends } from '../../../../hooks'; +import { ObjectLocationView } from '../object-location/ObjectLocationView'; + +export const FriendRequestDialogView: FC<{ roomIndex: number, request: MessengerRequest, hideFriendRequest: (userId: number) => void }> = props => +{ + const { roomIndex = -1, request = null, hideFriendRequest = null } = props; + const { requestResponse = null } = useFriends(); + + return ( + + + + + { LocalizeText('widget.friendrequest.from', [ 'username' ], [ request.name ]) } + hideFriendRequest(request.requesterUserId) } /> + + + + + + + + + ); +} diff --git a/src/components/room/widgets/friend-request/FriendRequestWidgetView.tsx b/src/components/room/widgets/friend-request/FriendRequestWidgetView.tsx index ba3f60d2..e009fb20 100644 --- a/src/components/room/widgets/friend-request/FriendRequestWidgetView.tsx +++ b/src/components/room/widgets/friend-request/FriendRequestWidgetView.tsx @@ -1,18 +1,16 @@ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { RoomObjectCategory, RoomObjectUserType } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; -import { LocalizeText, MessengerRequest, RoomWidgetUpdateRoomObjectEvent } from '../../../../api'; -import { Base, Button, Column, Flex, Text } from '../../../../common'; +import { MessengerRequest, RoomWidgetUpdateRoomObjectEvent } from '../../../../api'; import { UseEventDispatcherHook, useFriends } from '../../../../hooks'; import { useRoomContext } from '../../RoomContext'; -import { ObjectLocationView } from '../object-location/ObjectLocationView'; +import { FriendRequestDialogView } from './FriendRequestDialogView'; export const FriendRequestWidgetView: FC<{}> = props => { const [ displayedRequests, setDisplayedRequests ] = useState<{ roomIndex: number, request: MessengerRequest }[]>([]); const [ dismissedRequestIds, setDismissedRequestIds ] = useState([]); const { roomSession = null, eventDispatcher = null } = useRoomContext(); - const { requests = [], requestResponse = null } = useFriends(); + const { requests = [] } = useFriends(); const hideFriendRequest = (userId: number) => { @@ -89,35 +87,13 @@ export const FriendRequestWidgetView: FC<{}> = props => if(!requests.length) return null; - const FriendRequestDialogView: FC<{ roomIndex: number, request: MessengerRequest }> = props => - { - const { roomIndex = -1, request = null } = props; - - return ( - - - - - { LocalizeText('widget.friendrequest.from', [ 'username' ], [ request.name ]) } - hideFriendRequest(request.requesterUserId) } /> - - - - - - - - - ); - } - return ( <> { displayedRequests.map((request, index) => { if(dismissedRequestIds.indexOf(request.request.requesterUserId) >= 0) return null; - return ; + return ; }) } ); diff --git a/src/hooks/friends/useFriends.ts b/src/hooks/friends/useFriends.ts index 6b70c0d2..3094c54b 100644 --- a/src/hooks/friends/useFriends.ts +++ b/src/hooks/friends/useFriends.ts @@ -72,13 +72,13 @@ const useFriendsState = () => if(!canRequestFriend(userId)) return false; setSentRequests(prevValue => - { - const newSentRequests = [ ...prevValue ]; + { + const newSentRequests = [ ...prevValue ]; - newSentRequests.push(userId); + newSentRequests.push(userId); - return newSentRequests; - }); + return newSentRequests; + }); SendMessageComposer(new RequestFriendComposer(userName)); }, [ canRequestFriend ]); @@ -94,25 +94,25 @@ const useFriendsState = () => else { setRequests(prevValue => + { + const newRequests = [ ...prevValue ]; + const index = newRequests.findIndex(request => (request.id === requestId)); + + if(index === -1) return prevValue; + + if(flag) { - const newRequests = [ ...prevValue ]; - const index = newRequests.findIndex(request => (request.id === requestId)); + SendMessageComposer(new AcceptFriendMessageComposer(newRequests[index].id)); + } + else + { + SendMessageComposer(new DeclineFriendMessageComposer(false, newRequests[index].id)); + } - if(index === -1) return prevValue; + newRequests.splice(index, 1); - if(flag) - { - SendMessageComposer(new AcceptFriendMessageComposer(newRequests[index].id)); - } - else - { - SendMessageComposer(new DeclineFriendMessageComposer(false, newRequests[index].id)); - } - - newRequests.splice(index, 1); - - return newRequests; - }); + return newRequests; + }); } }, []); @@ -136,21 +136,21 @@ const useFriendsState = () => const parser = event.getParser(); setFriends(prevValue => + { + const newValue = [ ...prevValue ]; + + for(const friend of parser.fragment) { - const newValue = [ ...prevValue ]; + const index = newValue.findIndex(existingFriend => (existingFriend.id === friend.id)); + const newFriend = new MessengerFriend(); + newFriend.populate(friend); - for(const friend of parser.fragment) - { - const index = newValue.findIndex(existingFriend => (existingFriend.id === friend.id)); - const newFriend = new MessengerFriend(); - newFriend.populate(friend); + if(index > -1) newValue[index] = newFriend; + else newValue.push(newFriend); + } - if(index > -1) newValue[index] = newFriend; - else newValue.push(newFriend); - } - - return newValue; - }); + return newValue; + }); }, []); UseMessageEventHook(FriendListFragmentEvent, onFriendsFragmentEvent); @@ -160,39 +160,39 @@ const useFriendsState = () => const parser = event.getParser(); setFriends(prevValue => + { + const newValue = [ ...prevValue ]; + + const processUpdate = (friend: FriendParser) => { - const newValue = [ ...prevValue ]; + const index = newValue.findIndex(existingFriend => (existingFriend.id === friend.id)); - const processUpdate = (friend: FriendParser) => + if(index === -1) { - const index = newValue.findIndex(existingFriend => (existingFriend.id === friend.id)); + const newFriend = new MessengerFriend(); + newFriend.populate(friend); - if(index === -1) - { - const newFriend = new MessengerFriend(); - newFriend.populate(friend); - - newValue.unshift(newFriend); - } - else - { - newValue[index].populate(friend); - } + newValue.unshift(newFriend); } - - for(const friend of parser.addedFriends) processUpdate(friend); - - for(const friend of parser.updatedFriends) processUpdate(friend); - - for(const removedFriendId of parser.removedFriendIds) + else { - const index = newValue.findIndex(existingFriend => (existingFriend.id === removedFriendId)); - - if(index > -1) newValue.splice(index); + newValue[index].populate(friend); } + } - return newValue; - }); + for(const friend of parser.addedFriends) processUpdate(friend); + + for(const friend of parser.updatedFriends) processUpdate(friend); + + for(const removedFriendId of parser.removedFriendIds) + { + const index = newValue.findIndex(existingFriend => (existingFriend.id === removedFriendId)); + + if(index > -1) newValue.splice(index, 1); + } + + return newValue; + }); }, []); UseMessageEventHook(FriendListUpdateEvent, onFriendsUpdateEvent); @@ -202,29 +202,29 @@ const useFriendsState = () => const parser = event.getParser(); setRequests(prevValue => + { + const newValue = [ ...prevValue ]; + + for(const request of parser.requests) { - const newValue = [ ...prevValue ]; + const index = newValue.findIndex(existing => (existing.requesterUserId === request.requesterUserId)); - for(const request of parser.requests) + if(index > 0) { - const index = newValue.findIndex(existing => (existing.requesterUserId === request.requesterUserId)); - - if(index > 0) - { - newValue[index] = CloneObject(newValue[index]); - newValue[index].populate(request); - } - else - { - const newRequest = new MessengerRequest(); - newRequest.populate(request); - - newValue.push(newRequest); - } + newValue[index] = CloneObject(newValue[index]); + newValue[index].populate(request); } + else + { + const newRequest = new MessengerRequest(); + newRequest.populate(request); - return newValue; - }); + newValue.push(newRequest); + } + } + + return newValue; + }); }, []); UseMessageEventHook(FriendRequestsEvent, onFriendRequestsEvent); @@ -235,21 +235,21 @@ const useFriendsState = () => const request = parser.request; setRequests(prevValue => + { + const newRequests = [ ...prevValue ]; + + const index = newRequests.findIndex(existing => (existing.requesterUserId === request.requesterUserId)); + + if(index === -1) { - const newRequests = [ ...prevValue ]; + const newRequest = new MessengerRequest(); + newRequest.populate(request); - const index = newRequests.findIndex(existing => (existing.requesterUserId === request.requesterUserId)); + newRequests.push(newRequest); + } - if(index === -1) - { - const newRequest = new MessengerRequest(); - newRequest.populate(request); - - newRequests.push(newRequest); - } - - return newRequests; - }); + return newRequests; + }); }, []); UseMessageEventHook(NewFriendRequestEvent, onNewFriendRequestEvent); diff --git a/src/hooks/friends/useMessenger.ts b/src/hooks/friends/useMessenger.ts index 00259b21..2076ad46 100644 --- a/src/hooks/friends/useMessenger.ts +++ b/src/hooks/friends/useMessenger.ts @@ -29,70 +29,42 @@ const useMessengerState = () => thread = new MessengerThread(friend); setMessageThreads(prevValue => - { - const newValue = [ ...prevValue ]; + { + const newValue = [ ...prevValue ]; - newValue.push(thread); + newValue.push(thread); - return newValue; - }); + return newValue; + }); setHiddenThreadIds(prevValue => - { - const index = prevValue.indexOf(thread.threadId); + { + const index = prevValue.indexOf(thread.threadId); - if(index === -1) return prevValue; + if(index === -1) return prevValue; - const newValue = [ ...prevValue ]; + const newValue = [ ...prevValue ]; - newValue.splice(index, 1); + newValue.splice(index, 1); - return newValue; - }); + return newValue; + }); return thread; }, [ messageThreads, getFriend ]); - const setActiveThread = useCallback((thread: MessengerThread) => - { - if(!thread) - { - setActiveThreadId(-1); - - return; - } - - setMessageThreads(prevValue => - { - const newValue = [ ...prevValue ]; - const index = newValue.findIndex(newThread => (newThread.threadId === thread.threadId)); - - if(index === -1) return prevValue; - - const newThread = CloneObject(newValue[index]); - - newValue[index] = newThread; - - newThread.setRead(); - - return newValue; - }); - - setActiveThreadId(thread.threadId); - }, []); - const closeThread = (threadId: number) => { setHiddenThreadIds(prevValue => - { - const newValue = [ ...prevValue ]; + { + const newValue = [ ...prevValue ]; - if(newValue.indexOf(threadId) >= 0) return prevValue; + if(newValue.indexOf(threadId) >= 0) return prevValue; - newValue.push(threadId); + newValue.push(threadId); - return newValue; - }); + return newValue; + }); } const sendMessage = (thread: MessengerThread, text: string) => @@ -104,81 +76,103 @@ const useMessengerState = () => if((messageThreads.length === 1) && (thread.groups.length === 1)) PlaySound(SoundNames.MESSENGER_NEW_THREAD); setMessageThreads(prevValue => - { - const newValue = [ ...prevValue ]; - const index = newValue.findIndex(newThread => (newThread.threadId === thread.threadId)); + { + const newValue = [ ...prevValue ]; + const index = newValue.findIndex(newThread => (newThread.threadId === thread.threadId)); - if(index === -1) return prevValue; + if(index === -1) return prevValue; - const newThread = CloneObject(newValue[index]); + newValue[index] = CloneObject(newValue[index]); - newValue[index] = newThread; + thread = newValue[index]; - newThread.addMessage(GetSessionDataManager().userId, text, 0, null, MessengerThreadChat.CHAT); + thread.addMessage(GetSessionDataManager().userId, text, 0, null, MessengerThreadChat.CHAT); - if(activeThreadId === newThread.threadId) newThread.setRead(); + if(activeThreadId === thread.threadId) thread.setRead(); - return newValue; - }); + return newValue; + }); } const onNewConsoleMessageEvent = useCallback((event: NewConsoleMessageEvent) => { const parser = event.getParser(); - const thread = getMessageThread(parser.senderId); - - if(!thread) return; setMessageThreads(prevValue => + { + const newValue = [ ...prevValue ]; + + let existingIndex = newValue.findIndex(newThread => (newThread.participant && (newThread.participant.id === parser.senderId))); + let thread: MessengerThread = null; + + if(existingIndex === -1) { - const newValue = [ ...prevValue ]; - const index = newValue.findIndex(newThread => (newThread.threadId === thread.threadId)); + const friend = getFriend(parser.senderId); - if(index === -1) return prevValue; + if(friend) + { + thread = new MessengerThread(friend); - const newThread = CloneObject(newValue[index]); + newValue.push(thread); + } + } + else + { + newValue[existingIndex] = CloneObject(newValue[existingIndex]); - newValue[index] = newThread; + thread = newValue[existingIndex]; + } - newThread.addMessage(parser.senderId, parser.messageText, parser.secondsSinceSent, parser.extraData); + thread.addMessage(parser.senderId, parser.messageText, parser.secondsSinceSent, parser.extraData); - if(activeThreadId === newThread.threadId) newThread.setRead(); + if(activeThreadId === thread.threadId) thread.setRead(); - if(newThread.unreadCount > 0) PlaySound(SoundNames.MESSENGER_MESSAGE_RECEIVED); + if(thread.unreadCount > 0) PlaySound(SoundNames.MESSENGER_MESSAGE_RECEIVED); - return newValue; - }); - }, [ activeThreadId, getMessageThread ]); + return newValue; + }); + }, [ activeThreadId, getFriend ]); UseMessageEventHook(NewConsoleMessageEvent, onNewConsoleMessageEvent); const onRoomInviteEvent = useCallback((event: RoomInviteEvent) => { const parser = event.getParser(); - const thread = getMessageThread(parser.senderId); - - if(!thread) return; setMessageThreads(prevValue => + { + const newValue = [ ...prevValue ]; + + let existingIndex = newValue.findIndex(newThread => (newThread.participant && (newThread.participant.id === parser.senderId))); + let thread: MessengerThread = null; + + if(existingIndex === -1) { - const newValue = [ ...prevValue ]; - const index = newValue.findIndex(newThread => (newThread.threadId === thread.threadId)); + const friend = getFriend(parser.senderId); - if(index === -1) return prevValue; + if(friend) + { + thread = new MessengerThread(friend); - const newThread = CloneObject(newValue[index]); + newValue.push(thread); + } + } + else + { + newValue[existingIndex] = CloneObject(newValue[existingIndex]); - newValue[index] = newThread; + thread = newValue[existingIndex]; + } - newThread.addMessage(null, parser.messageText, 0, null, MessengerThreadChat.ROOM_INVITE); + thread.addMessage(null, parser.messageText, 0, null, MessengerThreadChat.ROOM_INVITE); - if(activeThreadId === newThread.threadId) newThread.setRead(); + if(activeThreadId === thread.threadId) thread.setRead(); - if(newThread.unreadCount > 0) PlaySound(SoundNames.MESSENGER_MESSAGE_RECEIVED); + if(thread.unreadCount > 0) PlaySound(SoundNames.MESSENGER_MESSAGE_RECEIVED); - return newValue; - }); - }, [ activeThreadId, getMessageThread ]); + return newValue; + }); + }, [ activeThreadId, getFriend ]); UseMessageEventHook(RoomInviteEvent, onRoomInviteEvent); @@ -192,31 +186,51 @@ const useMessengerState = () => UseMessageEventHook(RoomInviteErrorEvent, onRoomInviteErrorEvent); + useEffect(() => + { + if(activeThreadId <= 0) return; + + setMessageThreads(prevValue => + { + const newValue = [ ...prevValue ]; + + let existingIndex = newValue.findIndex(newThread => (newThread.threadId === activeThreadId)); + + if(existingIndex === -1) return; + + newValue[existingIndex] = CloneObject(newValue[existingIndex]); + + newValue[existingIndex].setRead(); + + return newValue; + }); + }, [ activeThreadId ]); + useEffect(() => { setIconState(prevValue => + { + if(!visibleThreads.length) return MessengerIconState.HIDDEN; + + let isUnread = false; + + for(const thread of visibleThreads) { - if(!visibleThreads.length) return MessengerIconState.HIDDEN; - - let isUnread = false; - - for(const thread of visibleThreads) + if(thread.unreadCount > 0) { - if(thread.unreadCount > 0) - { - isUnread = true; + isUnread = true; - break; - } + break; } + } - if(isUnread) return MessengerIconState.UNREAD; + if(isUnread) return MessengerIconState.UNREAD; - return MessengerIconState.SHOW; - }); + return MessengerIconState.SHOW; + }); }, [ visibleThreads ]); - return { messageThreads, activeThread, iconState, visibleThreads, getMessageThread, setActiveThread, closeThread, sendMessage }; + return { messageThreads, activeThread, iconState, visibleThreads, getMessageThread, setActiveThreadId, closeThread, sendMessage }; } export const useMessenger = () => useBetween(useMessengerState); diff --git a/src/hooks/inventory/common/index.ts b/src/hooks/inventory/common/index.ts deleted file mode 100644 index 9e408bb8..00000000 --- a/src/hooks/inventory/common/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './FurnitureUtilities'; -export * from './PetUtilities'; -export * from './TradingUtilities'; diff --git a/src/hooks/inventory/index.ts b/src/hooks/inventory/index.ts index 0d082803..4e70819c 100644 --- a/src/hooks/inventory/index.ts +++ b/src/hooks/inventory/index.ts @@ -1,4 +1,3 @@ -export * from './common'; export * from './useInventoryBadges'; export * from './useInventoryBots'; export * from './useInventoryFurni'; diff --git a/src/hooks/inventory/useInventoryFurni.ts b/src/hooks/inventory/useInventoryFurni.ts index 674ed136..8ce8379d 100644 --- a/src/hooks/inventory/useInventoryFurni.ts +++ b/src/hooks/inventory/useInventoryFurni.ts @@ -3,9 +3,8 @@ import { useCallback, useEffect, useState } from 'react'; import { useBetween } from 'use-between'; import { useInventoryUnseenTracker } from '.'; import { UseMessageEventHook } from '..'; -import { attemptItemPlacement, cancelRoomObjectPlacement, CloneObject, CreateLinkEvent, FurnitureItem, getPlacingItemId, GroupItem, SendMessageComposer, UnseenItemCategory } from '../../api'; +import { addFurnitureItem, attemptItemPlacement, cancelRoomObjectPlacement, CloneObject, CreateLinkEvent, FurnitureItem, getAllItemIds, getPlacingItemId, GroupItem, mergeFurniFragments, SendMessageComposer, UnseenItemCategory } from '../../api'; import { useSharedVisibility } from '../useSharedVisibility'; -import { addFurnitureItem, getAllItemIds, mergeFurniFragments } from './common'; let furniMsgFragments: Map[] = null; diff --git a/src/hooks/inventory/useInventoryPets.ts b/src/hooks/inventory/useInventoryPets.ts index f6e71f47..5ee4d0c1 100644 --- a/src/hooks/inventory/useInventoryPets.ts +++ b/src/hooks/inventory/useInventoryPets.ts @@ -3,10 +3,8 @@ import { useCallback, useEffect, useState } from 'react'; import { useBetween } from 'use-between'; import { useInventoryUnseenTracker } from '.'; import { UseMessageEventHook } from '..'; -import { SendMessageComposer, UnseenItemCategory } from '../../api'; -import { IPetItem } from '../../api/inventory/IPetItem'; +import { addSinglePetItem, IPetItem, mergePetFragments, processPetFragment, removePetItemById, SendMessageComposer, UnseenItemCategory } from '../../api'; import { useSharedVisibility } from '../useSharedVisibility'; -import { addSinglePetItem, mergePetFragments, processPetFragment, removePetItemById } from './common'; let petMsgFragments: Map[] = null; diff --git a/src/hooks/inventory/useInventoryTrade.ts b/src/hooks/inventory/useInventoryTrade.ts index b90d42f4..0d208b52 100644 --- a/src/hooks/inventory/useInventoryTrade.ts +++ b/src/hooks/inventory/useInventoryTrade.ts @@ -3,10 +3,9 @@ import { useCallback, useEffect, useState } from 'react'; import { useBetween } from 'use-between'; import { useInventoryFurni } from '.'; import { UseMessageEventHook } from '..'; -import { CloneObject, GetRoomSession, GetSessionDataManager, GroupItem, LocalizeText, NotificationUtilities, SendMessageComposer, TradeState, TradeUserData, TradingNotificationMessage, TradingNotificationType } from '../../api'; +import { CloneObject, GetRoomSession, GetSessionDataManager, GroupItem, LocalizeText, NotificationUtilities, parseTradeItems, SendMessageComposer, TradeState, TradeUserData, TradingNotificationMessage, TradingNotificationType } from '../../api'; import { InventoryTradeRequestEvent } from '../../events'; import { UseUiEvent } from '../events'; -import { parseTradeItems } from './common'; const useInventoryTradeState = () => {