src/services/userService.js
import { Adapter } from '../util/reactAdapter'
// Using matrixService from ditto in the meanwhile
import matrix from '../services/matrixService'
import User from '../models/User'
const debug = require('debug')('ditto:scenes:user:userService')
class UserService {
constructor () {
this._myUser = null
this._users = {}
this._syncList = {}
matrix.isReady$().subscribe((isReady) => {
if (isReady) this._listen()
})
}
//* *******************************************************************************
// Data
//* *******************************************************************************
getMyUser () {
if (!this._myUser) {
try {
const matrixUser = matrix.getClient().getUser(matrix.getClient().getUserId())
const user = new User(matrixUser.userId, matrixUser)
this._users[matrixUser.userId] = user
this._myUser = user
} catch (e) {
debug('Error in getMyUser', e)
}
}
return this._myUser
}
getUserById (userId) {
if (!this._users[userId]) {
this._users[userId] = new User(userId)
}
return this._users[userId]
}
_handleRoomStateEvent (event) {
if (event.getType() === 'm.room.member') {
const userId = event.getStateKey()
const newContent = event.getContent()
const prevContent = event.getPrevContent()
if (newContent.avatar_url !== prevContent.avatar_url) {
const matrixUser = matrix.getClient().getUser(userId)
// We need to update the avatar manually when the avatar has been removed
// because somehow the sdk doesn't
if (matrixUser.avatarUrl !== newContent.avatar_url) {
matrixUser.setAvatarUrl(newContent.avatar_url)
}
this._syncList[userId] = true
} else if (newContent.displayname !== prevContent.displayname) {
this._syncList[userId] = true
}
}
}
_listen () {
matrix.getClient().on('RoomState.events',
(event, roomState) => this._handleRoomStateEvent(event, roomState))
matrix.getClient().on('sync', (state) => {
if (['PREPARED', 'SYNCING'].includes(state)) {
Adapter.getInteractionManager().runAfterInteractions(this._syncUsers.bind(this))
}
})
}
_syncUsers () {
for (const userId of Object.keys(this._syncList)) {
if (this._users[userId]) this._users[userId].update()
}
this._syncList = {}
}
//* *******************************************************************************
// Helpers
//* *******************************************************************************
getAvatarUrl (url) {
return matrix.getImageUrl(url, 150, 150, 'crop')
}
getKnownUsers () {
const knownUsers = []
for (const matrixUser of matrix.getClient().getUsers()) {
if (matrixUser.userId &&
matrixUser.userId !== matrix.getClient().getUserId()) {
knownUsers.push({
id: matrixUser.userId,
name: matrixUser.displayName,
avatar: matrixUser.avatarUrl
})
}
}
return knownUsers
}
async searchUsers (searchText) {
try {
const { results: userList } = await matrix.getClient().searchUserDirectory({
term: searchText
})
const cleanUserList = []
for (const user of userList) {
// We need to remove duplicates and our own user
if (user.user_id !== matrix.getClient().getUserId() &&
cleanUserList.findIndex(cleanUser => cleanUser.id === user.user_id) === -1) {
cleanUserList.push({
id: user.user_id,
name: user.display_name,
avatar: user.avatar_url
})
}
}
return cleanUserList
} catch (e) {
debug('Error searching user directory', e)
}
}
}
const userService = new UserService()
export default userService