Skip to content
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

Merged
merged 34 commits into from
Apr 26, 2017
Merged

Add mention #362

merged 34 commits into from
Apr 26, 2017

Conversation

lijiarui
Copy link
Member

@lijiarui lijiarui commented Mar 26, 2017

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 3c9e1ea Merge 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...

@lijiarui
Copy link
Member Author

I feel a little bit strange for the continuous error:

src » message » ready() contact ready for ToUserName

I feel strange for two reasons:

  • it tests well on my computer, but it failed in the test.
  • I didn't change any function about m.ready() but it occurs test failed...

@coveralls
Copy link

Coverage Status

Coverage increased (+0.4%) to 56.13% when pulling f81e60a on lijiarui:add_mention into 2f18936 on Chatie:master.

@huan huan requested review from dcsan, xinbenlv and mukaiu March 26, 2017 22:27
Copy link
Member

@huan huan left a 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
Copy link
Member

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
Copy link
Member

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
}

Copy link
Member Author

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)
Copy link
Member

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})
Copy link
Member

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.

Copy link
Member Author

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)
Copy link
Member

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.

Copy link
Member Author

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)
}
Copy link
Member

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.
    }

Copy link
Member

@huan huan left a 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 () {
Copy link
Member

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.

@coveralls
Copy link

coveralls commented Mar 27, 2017

Coverage Status

Coverage increased (+0.3%) to 56.066% when pulling e2a98e7 on lijiarui:add_mention into 2f18936 on Chatie:master.

@coveralls
Copy link

coveralls commented Apr 16, 2017

Coverage Status

Coverage decreased (-0.5%) to 54.257% when pulling 253025d on lijiarui:add_mention into 3c6b575 on Chatie:master.

@huan
Copy link
Member

huan commented Apr 16, 2017

@lijiarui Could you write a summary of all the details about the mentioned feature to the issue or a new wiki page?

I'd like to see:

  1. how to identify the magic number
  2. what's the different behavior between the platforms(android/ios/web)

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))
Copy link
Member Author

@lijiarui lijiarui Apr 19, 2017

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.

Copy link
Member Author

@lijiarui lijiarui left a 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 {
Copy link
Member Author

@lijiarui lijiarui Apr 19, 2017

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

  1. using split(String.fromCharCode(8197)) get array ['Let me introduce @lijiarui@wechaty@beijing', ', she is a wechaty contributor']
  2. using filter(e => e.indexOf('@') > -1) to filter ', she is a wechaty contributor'
  3. using const list = e.split('@') to get array ['Let me introduce ','@lijiarui', '@wechaty', '@beijing']
  4. 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
}
})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. here to deal with multiple @ string, the for cyclic to get the continuous @ string end with the list last element. for example, e = 'Let me introduce @lijiarui@wechaty@beijing', then list = ['Let me introduce ','@lijiarui','@wechaty','@beijing'], after for cyclic, we get nickList = ['beijing','wechaty@beijing','lijiarui@wechaty@beijing']

Copy link
Contributor

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...:)

@lijiarui
Copy link
Member Author

lijiarui commented Apr 22, 2017

about message mention event:

Web Mac PC Client iOS Mobile android Mobile
[You were mentioned] tip ([有人@我]提示)
Identify magic code (8197) by copy & paste in mobile
Identify magic code (8197) by programming
Identify two contacts with the same roomAlias by [You were mentioned] tip

src/message.ts Outdated
}
return nickList
}
})
Copy link
Contributor

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...:)

@huan
Copy link
Member

huan commented Apr 22, 2017

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:

  1. your message mention event table and
  2. your explaination(reply/review) of your PR

Because your code is still hard to read/understand, it will be better with the comments.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 55.059% when pulling 0c828c2 on lijiarui:add_mention into 3c6b575 on Chatie:master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 55.059% when pulling 0c828c2 on lijiarui:add_mention into 3c6b575 on Chatie:master.

@lijiarui
Copy link
Member Author

@zixia Could you merge this time or give some suggestion?
thanks

Copy link
Member

@huan huan left a 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 => {
Copy link
Member

@huan huan Apr 24, 2017

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))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Define the magic char, instead of direct use it.
  2. Keep your naming style consist. use StrList instead of Strings
  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 => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Do not use var name strings because it will be very confusing with string
  2. Do not use a map inline function with so many lines.
  3. Do not use e as the var name. Because e stands for event, error, etc. use s/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) => {
Copy link
Member

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[] = []
Copy link
Member

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.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 55.053% when pulling 5df7b78 on lijiarui:add_mention into 3c6b575 on Chatie:master.

Copy link
Member

@huan huan left a 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)?

@huan huan merged commit 6750d19 into wechaty:master Apr 26, 2017
@lijiarui
Copy link
Member Author

I'll pr room.say() by magic code, but as mention table showed, it won't get red [You were mentioned] tip on mobile wechat. While anyway, it should change.

@huan
Copy link
Member

huan commented Apr 26, 2017

Awesome, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants