-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add mention #362
Add mention #362
Conversation
I feel a little bit strange for the continuous error: src » message » ready() contact ready for ToUserName I feel strange for two reasons:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR looks good to me.
Please follow my reviews, and add more unit test cases if you can.
src/message.ts
Outdated
@@ -403,6 +403,37 @@ export class Message implements Sayable { | |||
return fromId === userId | |||
} | |||
|
|||
/** | |||
* Get the mentioned contact which the message is mentioned for. | |||
* @returns {Contact[]} return the contactList which the message is mentioned for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a @example
here.
src/message.ts
Outdated
let contactList: Contact[] = [] | ||
const room = this.room() | ||
if (!room) return contactList | ||
if (this.type() !== MsgType.TEXT) return contactList |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please always use {}
for if
, even if there's only one line of code, because that will make code more readable.
if (this.type() !== MsgType.TEXT
|| !this.room) {
return contactList
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cannot use this.room
instead of room
here, or typescript will see this.room
is null.
src/message.ts
Outdated
|
||
const mentionList = foundList.map(element => { | ||
/** | ||
* fake '@' return element.slice(1, -1), wechat real '@' return element.slice(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can not understand your comment.
Please provide a example in comments to make it clear.
src/message.ts
Outdated
}) | ||
log.verbose('Message', 'mention(%s),get mentionList: %s', this.content(), JSON.stringify(mentionList)) | ||
mentionList.forEach(name => { | ||
const contact = room.member({alias: name}) || room.member({name: name}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe here should use room.member(name)
instead of your code, which will require you to fix the member()
method first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here should never use room.member(name)
, because room.member(name)
will get all three kinds of names here. But we just use two of them, and if parse room.member({contactAlias: name})
will get the contact which we doesn't meant to parse.
src/message.ts
Outdated
if (!room) return contactList | ||
if (this.type() !== MsgType.TEXT) return contactList | ||
|
||
const foundList = this.content().match(/@\S+ ?/g) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, the foundList will contains all the strings following by a @
character?
I suggest renaming foundList
to atStringList
to make it more clear and readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, the foundeList will contains all the shortest string following by a @
character.
If ones' wechat name is lijiarui@orange
, it will return orange
, instead of lijiarui@orange
.
Or, we should permutation and combination all the possibility.....
What do you think about it?
src/message.ts
Outdated
const contact = room.member({alias: name}) || room.member({name: name}) | ||
if (contact) { | ||
contactList.push(contact) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to make sure the code is running as expected.
if (contact) {
contactList.push(contact)
} else {
log.warn('Message', 'mention() can not found room.member() from mentionList')
// this will help us to track the unexpected strings.
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more thing...
const room11 = msg11.room() | ||
if (room11) { | ||
await room11.ready() | ||
setTimeout(function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd better find out why you need setTimeout
at here, or you will be more likely to be bitten again and again.
@lijiarui Could you write a summary of all the details about the I'd like to see:
You could also consider writing a blog post about this story too, because it will be very interesting. |
src/message.ts
Outdated
return contactList | ||
} | ||
|
||
const atStrings = this.content().split(String.fromCharCode(8197)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trying to split array with magic code 8197
and get strings atStrings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@xinbenlv Sorry for reply late...
description as follows:
src/message.ts
Outdated
const list = e.split('@') | ||
if (list.length < 3) { | ||
return [e.slice(e.lastIndexOf('@') + 1)] | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using filter(e => e.indexOf('@') > -1)
to filter the string without @
.
for example, a message: Let me introduce @lijiarui@wechaty@beijing , she is a wechaty contributor
- using
split(String.fromCharCode(8197))
get array['Let me introduce @lijiarui@wechaty@beijing', ', she is a wechaty contributor']
- using
filter(e => e.indexOf('@') > -1)
to filter', she is a wechaty contributor'
- using
const list = e.split('@')
to get array['Let me introduce ','@lijiarui', '@wechaty', '@beijing']
if (list.length < 3)
means the array just have less than 2 element, which@contact
doesn't have multiple@
signs, then return@
string into mentionList.
src/message.ts
Outdated
} | ||
return nickList | ||
} | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- here to deal with multiple
@
string, the for cyclic to get the continuous@
string end with thelist
last element. for example,e = 'Let me introduce @lijiarui@wechaty@beijing'
, thenlist = ['Let me introduce ','@lijiarui','@wechaty','@beijing']
, after for cyclic, we getnickList = ['beijing','wechaty@beijing','lijiarui@wechaty@beijing']
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will approve it, but this part is a little hard to read...:)
about message mention event:
|
src/message.ts
Outdated
} | ||
return nickList | ||
} | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will approve it, but this part is a little hard to read...:)
Thanks all for approving this PR. @lijiarui Could you please add comments to document the function? I want you to at least include the following part:
Because your code is still hard to read/understand, it will be better with the comments. |
1 similar comment
@zixia Could you merge this time or give some suggestion? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see my comments and let me know what you think. Thanks.
src/message.ts
Outdated
}, []) | ||
|
||
log.verbose('Message', 'mentioned(%s),get mentionList: %s', this.content(), JSON.stringify(mentionList)) | ||
mentionList.forEach(name => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use this line to replace the 15 lines forEach function:
contactList = mentionList.map(room.memberAll.bind(room)).filter(c => !!c)
Maybe you need to flatten it by var merged = [].concat.apply([], arrays)
See http://stackoverflow.com/a/10865042/1123955
src/message.ts
Outdated
// Example: `Let me introduce @lijiarui@wechaty@beijing , she is a wechaty contributor` | ||
// Trying to split array with magic code `8197` and get atStrings | ||
// Example result: atStrings = ['Let me introduce @lijiarui@wechaty@beijing', ', she is a wechaty contributor'] | ||
const atStrings = this.content().split(String.fromCharCode(8197)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Define the magic char, instead of direct use it.
- Keep your naming style consist. use
StrList
instead ofStrings
const AT_SEPRATOR = String.fromCharCode(8197)
const atStrList = this.content().split(AT_SEPRATOR)
src/message.ts
Outdated
|
||
// Using `filter(e => e.indexOf('@') > -1)` to filter the string without `@` | ||
// Example result: atStrings.filter(e => e.indexOf('@') > -1) = ['Let me introduce @lijiarui@wechaty@beijing'] | ||
const strings = atStrings.filter(e => e.indexOf('@') > -1).map(e => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Do not use var name
strings
because it will be very confusing withstring
- Do not use a map inline function with so many lines.
- Do not use
e
as the var name. Becausee
stands forevent
,error
, etc. uses
/str
for the string instead.
I can not understand the code inside this map function.
However, I would like to rewrite this huge map function like this:
const mentionedStringList = atStrList
.filter(str => str.include('@))
.map(str => str.replace(/^.*?@/, '@'))
src/message.ts
Outdated
} | ||
}) | ||
.filter(e => !!e) // filter blank string | ||
const mentionList = strings.reduce((acc, val) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this reduce
function meaning for?
I feel the mentionList will be equal to your strings
array.
src/message.ts
Outdated
// 2. element are continuous, eg: [3],[2,3],[1,2,3] | ||
|
||
// Here: list = ['Let me introduce ','@lijiarui', '@wechaty', '@beijing'] | ||
let nickList: string[] = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const str = '@a@b@c'
let tryName = ''
const tryNameList = []
str.split('@')
.filter(c => !!c)
.forEach(c => {
tryName += '@' + c
tryNameList.push(tryName.slice(1)) // get rid of the `@` at beginning
})
console.log(tryNameList)
will output: [ 'a', 'a@b', 'a@b@c' ]
Please use the above code to replace your for loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks great!
Can we use the magic mention character to enable mention someone by room.say(text, contact)
?
I'll pr |
Awesome, thanks! |
continue with #287
I'm trying to reset the merge file. Becasue the
ding
error is not casued by this commit, so I should reset the commit 3c9e1eaMerge branch 'master' of https://github.com/wechaty/wechaty into add_mention
As I have said in #287, thanks god, finally I mocked room data successfully...