From 859c2260bb4e151f1abef5d0ed5c4012ba46dfe6 Mon Sep 17 00:00:00 2001 From: lijiarui Date: Wed, 5 Apr 2017 07:26:08 +0800 Subject: [PATCH] room.memberAll() & change room.member() query to 3 types (#364) * room.memberAll() & change room.member() query to 3 types * recover message.ts * change alias to roomAlias * recomver message.spec * recover merge by mistake * change roomAlias to alias based on semantic * keep alias be simple and explicit roomAlias and contactAlias --- src/room.ts | 96 ++++++++++++++++++++++++++++++++++------------- test/room.spec.ts | 13 ++++--- 2 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/room.ts b/src/room.ts index 1740398a..789a9318 100644 --- a/src/room.ts +++ b/src/room.ts @@ -10,16 +10,17 @@ import { Message } from './message' import { UtilLib } from './util-lib' type RoomObj = { - id: string, - encryId: string, - topic: string, - ownerUin: number, - memberList: Contact[], - nameMap: Map, - aliasMap: Map, + id: string, + encryId: string, + topic: string, + ownerUin: number, + memberList: Contact[], + nameMap: Map, + roomAliasMap: Map, + contactAliasMap: Map, } -type NameType = 'name' | 'alias' +type NameType = 'name' | 'alias' | 'roomAlias' | 'contactAlias' export type RoomRawMember = { UserName: string, @@ -46,8 +47,10 @@ export type RoomQueryFilter = { } export type MemberQueryFilter = { - name?: string, - alias?: string, + name?: string, + alias?: string, + roomAlias?: string, + contactAlias?: string, } /** @@ -198,7 +201,8 @@ export class Room extends EventEmitter implements Sayable { .map(m => Contact.load(m.UserName)) const nameMap = this.parseMap('name', rawObj.MemberList) - const aliasMap = this.parseMap('alias', rawObj.MemberList) + const roomAliasMap = this.parseMap('roomAlias', rawObj.MemberList) + const contactAliasMap = this.parseMap('contactAlias', rawObj.MemberList) return { id: rawObj.UserName, @@ -207,7 +211,8 @@ export class Room extends EventEmitter implements Sayable { ownerUin: rawObj.OwnerUin, memberList, nameMap, - aliasMap, + roomAliasMap, + contactAliasMap, } } @@ -219,11 +224,14 @@ export class Room extends EventEmitter implements Sayable { let contact = Contact.load(member.UserName) switch (parseContent) { case 'name': - tmpName = contact.alias() || contact.name() + tmpName = contact.name() break - case 'alias': + case 'roomAlias': tmpName = member.DisplayName break + case 'contactAlias': + tmpName = contact.alias() || '' + break default: throw new Error('parseMap failed, member not found') } @@ -340,15 +348,19 @@ export class Room extends EventEmitter implements Sayable { } /** - * return contact's roomAlias in the room + * return contact's roomAlias in the room, the same as roomAlias * @param {Contact} contact * @returns {string | null} If a contact has an alias in room, return string, otherwise return null */ public alias(contact: Contact): string | null { - if (!this.obj || !this.obj.aliasMap) { + return this.roomAlias(contact) + } + + public roomAlias(contact: Contact): string | null { + if (!this.obj || !this.obj.roomAliasMap) { return null } - return this.obj.aliasMap[contact.id] || null + return this.obj.roomAliasMap[contact.id] || null } public has(contact: Contact): boolean { @@ -378,15 +390,28 @@ export class Room extends EventEmitter implements Sayable { } /** - * find member priority by `name`(contactAlias) / `alias`(roomAlias) - * when use member(name:string), equals to member({name:string}) + * find member by name | roomAlias(alias) | contactAlias + * when use memberAll(name:string), return all matched members, including name, roomAlias, contactAlias */ - public member(filter: MemberQueryFilter): Contact | null - public member(name: string): Contact | null + public memberAll(filter: MemberQueryFilter): Contact[] | null + public memberAll(name: string): Contact[] | null - public member(queryArg: MemberQueryFilter | string): Contact | null { + public memberAll(queryArg: MemberQueryFilter | string): Contact[] | null { if (typeof queryArg === 'string') { - return this.member({name: queryArg}) + let contactList: Contact[] = [] + const nameList = this.memberAll({name: queryArg}) + const roomAliasList = this.memberAll({roomAlias: queryArg}) + const contactAliasList = this.memberAll({contactAlias: queryArg}) + if (nameList) { + contactList = contactList.concat(nameList) + } + if (roomAliasList) { + contactList = contactList.concat(roomAliasList) + } + if (contactAliasList) { + contactList = contactList.concat(contactAliasList) + } + return contactList } log.silly('Room', 'member({ %s })', @@ -410,8 +435,10 @@ export class Room extends EventEmitter implements Sayable { let filterValue: string = UtilLib.stripEmoji(queryArg[filterKey]) const keyMap = { - name: 'nameMap', - alias: 'aliasMap', + name: 'nameMap', + roomAlias: 'roomAliasMap', + alias: 'roomAliasMap', + contactAlias: 'contactAliasMap', } filterKey = keyMap[filterKey] @@ -430,12 +457,29 @@ export class Room extends EventEmitter implements Sayable { log.silly('Room', 'member() check %s from %s: %s', filterValue, filterKey, JSON.stringify(filterMap)) if (idList.length) { - return Contact.load(idList[0]) + return idList.map(id => Contact.load(id)) } else { return null } } + public member(filter: MemberQueryFilter): Contact | null + public member(name: string): Contact | null + + public member(queryArg: MemberQueryFilter | string): Contact | null { + log.verbose('Room', 'member(%s)', JSON.stringify(queryArg)) + + const memberList = this.memberAll(queryArg) + if (!memberList || !memberList.length) { + return null + } + + if (memberList.length > 1) { + log.warn('Room', 'function member(%s) get %d contacts, use the first one by default', JSON.stringify(queryArg), memberList.length) + } + return memberList[0] + } + public memberList(): Contact[] { log.verbose('Room', 'memberList') diff --git a/test/room.spec.ts b/test/room.spec.ts index fe1ad42b..a113dbaa 100644 --- a/test/room.spec.ts +++ b/test/room.spec.ts @@ -135,20 +135,21 @@ test('Room smoking test', async t => { const contactB = r.member(EXPECTED.memberNick2) const contactC = r.member(EXPECTED.memberNick3) const contactD = r.member({alias: EXPECTED.memberNick1}) - if (contactA) { - throw new Error(`member(${EXPECTED.memberNick1}) cannot get contact by roomAlias`) + if (!contactA) { + throw new Error(`member(${EXPECTED.memberNick1}) should get member by roomAlias by default`) } if (!contactB) { - throw new Error(`member(${EXPECTED.memberNick2}) should get member by name when the contact does not have contactAlias`) + throw new Error(`member(${EXPECTED.memberNick2}) should get member by name by default`) } if (!contactC) { - throw new Error(`member(${EXPECTED.memberNick3}) should get member by name when the contact have contactAlias`) + throw new Error(`member(${EXPECTED.memberNick3}) should get member by name by default`) } if (!contactD) { throw new Error(`member({alias: ${EXPECTED.memberNick3}}) should get member by roomAlias`) } - t.is(contactB.id, EXPECTED.memberId2, `should get the right id from ${EXPECTED.memberId2}, find member by when the contact does not have contactAlias`) - t.is(contactC.id, EXPECTED.memberId3, `should get the right id from ${EXPECTED.memberId3}, find member by when the contact have contactAlias`) + t.is(contactA.id, EXPECTED.memberId1, `should get the right id from ${EXPECTED.memberId1}, find member by default`) + t.is(contactB.id, EXPECTED.memberId2, `should get the right id from ${EXPECTED.memberId2}, find member by default`) + t.is(contactC.id, EXPECTED.memberId3, `should get the right id from ${EXPECTED.memberId3}, find member by default`) t.is(contactD.id, EXPECTED.memberId1, `should get the right id from ${EXPECTED.memberId1}, find member by roomAlias`) const s = r.toString() -- GitLab