Skip to content

Commit

Permalink
Changes for user-relationship service to use schema, knex & feathers …
Browse files Browse the repository at this point in the history
…5 (#8451)

* Changes for user-relationship service to use schema, knex & feathers 5

* Updated resolvers to include user and related user objects

* Updated model

* Added migration

* Added index in migration

* Fixed id key name

* Moved validators from hooks to schema

* Updated model and schema

* Updated models and migration

* Updated migration

* Updated friend relationship

* Updated friend menu

* Fixed transaction not commited issue

* Updated variable name
  • Loading branch information
hanzlamateen authored Aug 19, 2023
1 parent 895536d commit 14cca79
Show file tree
Hide file tree
Showing 25 changed files with 684 additions and 524 deletions.
57 changes: 26 additions & 31 deletions packages/client-core/src/social/services/FriendService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ import { useEffect } from 'react'
import multiLogger from '@etherealengine/common/src/logger'
import { matches, Validator } from '@etherealengine/engine/src/common/functions/MatchesUtils'
import { Engine } from '@etherealengine/engine/src/ecs/classes/Engine'
import { Relationship } from '@etherealengine/engine/src/schemas/interfaces/Relationship'
import { defineAction, defineState, dispatchAction, getMutableState, getState } from '@etherealengine/hyperflux'

import { UserID, UserType } from '@etherealengine/engine/src/schemas/user/user.schema'
import {
userRelationshipPath,
UserRelationshipType
} from '@etherealengine/engine/src/schemas/user/user-relationship.schema'
import { UserID } from '@etherealengine/engine/src/schemas/user/user.schema'
import { Paginated } from '@feathersjs/feathers'
import { NotificationService } from '../../common/services/NotificationService'
import { AuthState } from '../../user/services/AuthService'

Expand All @@ -42,13 +46,7 @@ const logger = multiLogger.child({ component: 'client-core:FriendService' })
export const FriendState = defineState({
name: 'FriendState',
initial: () => ({
relationships: {
blocked: [] as Array<UserType>,
blocking: [] as Array<UserType>,
friend: [] as Array<UserType>,
requested: [] as Array<UserType>,
pending: [] as Array<UserType>
},
relationships: [] as UserRelationshipType[],
isFetching: false,
updateNeeded: true
})
Expand All @@ -61,13 +59,7 @@ export const FriendServiceReceptor = (action) => {
return s.isFetching.set(true)
})
.when(FriendAction.loadedFriendsAction.matches, (action) => {
s.relationships.merge({
blocked: action.relationships.blocked,
blocking: action.relationships.blocking,
friend: action.relationships.friend,
requested: action.relationships.requested,
pending: action.relationships.pending
})
s.relationships.set(action.relationships)
s.updateNeeded.set(false)
s.isFetching.set(false)
return
Expand All @@ -80,12 +72,14 @@ export const FriendService = {
try {
dispatchAction(FriendAction.fetchingFriendsAction({}))

const relationships: Relationship = await Engine.instance.api.service('user-relationship').find({
const relationships = (await Engine.instance.api.service(userRelationshipPath).find({
query: {
userId
userId,
$limit: 100
}
})
dispatchAction(FriendAction.loadedFriendsAction({ relationships }))
})) as Paginated<UserRelationshipType>

dispatchAction(FriendAction.loadedFriendsAction({ relationships: relationships.data }))
} catch (err) {
logger.error(err)
}
Expand All @@ -95,7 +89,7 @@ export const FriendService = {
},
acceptFriend: async (userId: UserID, relatedUserId: UserID) => {
try {
await Engine.instance.api.service('user-relationship').patch(relatedUserId, {
await Engine.instance.api.service(userRelationshipPath).patch(relatedUserId, {
userRelationshipType: 'friend'
})

Expand Down Expand Up @@ -143,24 +137,25 @@ export const FriendService = {
FriendService.getUserRelationship(selfUser.id)
}

Engine.instance.api.service('user-relationship').on('created', userRelationshipCreatedListener)
Engine.instance.api.service('user-relationship').on('patched', userRelationshipPatchedListener)
Engine.instance.api.service('user-relationship').on('removed', userRelationshipRemovedListener)
Engine.instance.api.service(userRelationshipPath).on('created', userRelationshipCreatedListener)
Engine.instance.api.service(userRelationshipPath).on('patched', userRelationshipPatchedListener)
Engine.instance.api.service(userRelationshipPath).on('removed', userRelationshipRemovedListener)

return () => {
Engine.instance.api.service('user-relationship').off('created', userRelationshipCreatedListener)
Engine.instance.api.service('user-relationship').off('patched', userRelationshipPatchedListener)
Engine.instance.api.service('user-relationship').off('removed', userRelationshipRemovedListener)
Engine.instance.api.service(userRelationshipPath).off('created', userRelationshipCreatedListener)
Engine.instance.api.service(userRelationshipPath).off('patched', userRelationshipPatchedListener)
Engine.instance.api.service(userRelationshipPath).off('removed', userRelationshipRemovedListener)
}
}, [])
}
}

async function createRelation(userId: UserID, relatedUserId: UserID, type: 'requested' | 'blocking') {
try {
await Engine.instance.api.service('user-relationship').create({
await Engine.instance.api.service(userRelationshipPath).create({
relatedUserId,
userRelationshipType: type
userRelationshipType: type,
userId: '' as UserID
})

FriendService.getUserRelationship(userId)
Expand All @@ -171,7 +166,7 @@ async function createRelation(userId: UserID, relatedUserId: UserID, type: 'requ

async function removeRelation(userId: UserID, relatedUserId: UserID) {
try {
await Engine.instance.api.service('user-relationship').remove(relatedUserId)
await Engine.instance.api.service(userRelationshipPath).remove(relatedUserId)

FriendService.getUserRelationship(userId)
} catch (err) {
Expand All @@ -187,6 +182,6 @@ export class FriendAction {

static loadedFriendsAction = defineAction({
type: 'ee.client.Friend.LOADED_FRIENDS' as const,
relationships: matches.object as Validator<unknown, Relationship>
relationships: matches.object as Validator<unknown, UserRelationshipType[]>
})
}
20 changes: 15 additions & 5 deletions packages/client-core/src/systems/ui/UserMenuView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,21 @@ const AvatarContextMenu = () => {
const user = peers ? Array.from(peers).find((peer) => peer.userId === detailState.id.value) || undefined : undefined
const { t } = useTranslation()

const isFriend = friendState.relationships.friend.value.find((item) => item.id === user?.userId)
const isRequested = friendState.relationships.requested.value.find((item) => item.id === user?.userId)
const isPending = friendState.relationships.pending.value.find((item) => item.id === user?.userId)
const isBlocked = friendState.relationships.blocked.value.find((item) => item.id === user?.userId)
const isBlocking = friendState.relationships.blocking.value.find((item) => item.id === user?.userId)
const isFriend = friendState.relationships.value.find(
(item) => item.relatedUserId === user?.userId && item.userRelationshipType === 'friend'
)
const isRequested = friendState.relationships.value.find(
(item) => item.relatedUserId === user?.userId && item.userRelationshipType === 'requested'
)
const isPending = friendState.relationships.value.find(
(item) => item.relatedUserId === user?.userId && item.userRelationshipType === 'pending'
)
const isBlocked = friendState.relationships.value.find(
(item) => item.relatedUserId === user?.userId && item.userRelationshipType === 'blocked'
)
const isBlocking = friendState.relationships.value.find(
(item) => item.relatedUserId === user?.userId && item.userRelationshipType === 'blocking'
)

const handleMute = () => {
console.log('Mute pressed')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,32 @@ const AvatarContextMenu = ({ onBack }: Props): JSX.Element => {
const authState = useHookstate(getMutableState(AuthState))
const selfId = authState.user.id?.value ?? ''

const userAvatarDetails = useHookstate(getMutableState(WorldState).userAvatarDetails)

const isFriend = friendState.relationships.friend.get({ noproxy: true }).find((item) => item.id === userId)
const isRequested = friendState.relationships.requested.get({ noproxy: true }).find((item) => item.id === userId)
const isPending = friendState.relationships.pending.get({ noproxy: true }).find((item) => item.id === userId)
const isBlocked = friendState.relationships.blocked.get({ noproxy: true }).find((item) => item.id === userId)
const isBlocking = friendState.relationships.blocking.get({ noproxy: true }).find((item) => item.id === userId)
const isFriend = friendState.relationships
.get({ noproxy: true })
.find((item) => item.relatedUserId === userId && item.userRelationshipType === 'friend')
const isRequested = friendState.relationships
.get({ noproxy: true })
.find((item) => item.relatedUserId === userId && item.userRelationshipType === 'requested')
const isPending = friendState.relationships
.get({ noproxy: true })
.find((item) => item.relatedUserId === userId && item.userRelationshipType === 'pending')
const isBlocked = friendState.relationships
.get({ noproxy: true })
.find((item) => item.relatedUserId === userId && item.userRelationshipType === 'blocked')
const isBlocking = friendState.relationships
.get({ noproxy: true })
.find((item) => item.relatedUserId === userId && item.userRelationshipType === 'blocking')

const userName = isFriend
? isFriend.name
? isFriend.relatedUser.name
: isRequested
? isRequested.name
? isRequested.relatedUser.name
: isPending
? isPending.name
? isPending.relatedUser.name
: isBlocked
? isBlocked.name
? isBlocked.relatedUser.name
: isBlocking
? isBlocking.name
? isBlocking.relatedUser.name
: worldState.userNames[userId].value ?? 'A user'

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,16 @@ const FriendsMenu = ({ defaultSelectedTab }: Props): JSX.Element => {
}

const displayList: Array<DisplayedUserInterface> = []
const pendingList: Array<DisplayedUserInterface> = friendState.relationships.value
.filter((item) => item.userRelationshipType === 'pending')
.map((item) => ({ id: item.relatedUserId, name: item.relatedUser.name, relationType: 'pending' as const }))
const friendList: Array<DisplayedUserInterface> = friendState.relationships.value
.filter((item) => item.userRelationshipType === 'friend')
.map((item) => ({ id: item.relatedUserId, name: item.relatedUser.name, relationType: 'friend' as const }))

if (selectedTab.value === 'friends') {
displayList.push(...friendState.relationships.pending.value)
displayList.push(...friendState.relationships.friend.value)
displayList.push(...pendingList)
displayList.push(...friendList)
} else if (selectedTab.value === 'messages') {
displayList.push(
...privateChannels.map((channel) => ({
Expand All @@ -153,17 +159,28 @@ const FriendsMenu = ({ defaultSelectedTab }: Props): JSX.Element => {
}))
)
} else if (selectedTab.value === 'blocked') {
displayList.push(...friendState.relationships.blocking.value)
const blockingList: Array<DisplayedUserInterface> = friendState.relationships.value
.filter((item) => item.userRelationshipType === 'blocking')
.map((item) => ({ id: item.relatedUserId, name: item.relatedUser.name, relationType: 'blocking' as const }))
displayList.push(...blockingList)
} else if (selectedTab.value === 'find') {
const layerPeers = Engine.instance.worldNetworkState?.peers
? Array.from(Engine.instance.worldNetworkState.peers.get({ noproxy: true }).values()).filter(
(peer) =>
peer.peerID !== 'server' &&
peer.userId !== userId &&
!friendState.relationships.friend.value.find((item) => item.id === peer.userId) &&
!friendState.relationships.pending.value.find((item) => item.id === peer.userId) &&
!friendState.relationships.blocked.value.find((item) => item.id === peer.userId) &&
!friendState.relationships.blocking.value.find((item) => item.id === peer.userId)
!friendState.relationships.value.find(
(item) => item.relatedUserId === peer.userId && item.userRelationshipType === 'friend'
) &&
!friendState.relationships.value.find(
(item) => item.relatedUserId === peer.userId && item.userRelationshipType === 'pending'
) &&
!friendState.relationships.value.find(
(item) => item.relatedUserId === peer.userId && item.userRelationshipType === 'blocked'
) &&
!friendState.relationships.value.find(
(item) => item.relatedUserId === peer.userId && item.userRelationshipType === 'blocking'
)
)
: []
displayList.push(
Expand All @@ -173,7 +190,12 @@ const FriendsMenu = ({ defaultSelectedTab }: Props): JSX.Element => {
)

displayList.forEach((peer) => {
if (friendState.relationships.requested.value.find((item) => item.id === peer.id)) peer.relationType = 'requested'
if (
friendState.relationships.value.find(
(item) => item.relatedUserId === peer.id && item.userRelationshipType === 'requested'
)
)
peer.relationType = 'requested'
})
}

Expand Down
12 changes: 12 additions & 0 deletions packages/common/src/dbmodels/UserInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,15 @@ export interface UserSetting {
id: string
themeModes: string
}

export interface UserRelationshipInterface {
id: string
userId: string
relatedUserId: string
userRelationshipType: 'friend' | 'requested'
dataValues: any
}

export interface UserRelationshipTypeInterface {
type: string
}
38 changes: 0 additions & 38 deletions packages/common/src/dbmodels/UserRelationship.ts

This file was deleted.

36 changes: 0 additions & 36 deletions packages/common/src/interfaces/UserRelationship.ts

This file was deleted.

39 changes: 0 additions & 39 deletions packages/engine/src/schemas/interfaces/Relationship.ts

This file was deleted.

Loading

0 comments on commit 14cca79

Please sign in to comment.