-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
filter: Implement has: filters on client side. #15492
Conversation
@timabbott created a separate PR for implementing the way you suggested in #15363 (comment) I want to ask one thing, emoji like :zulip: are also images should the filter include them as well in |
// We dont want to locally echo those has: messages | ||
// because: | ||
// 1. has:image, has:attachment are backend only syntax. | ||
// 2. has:link do not get displayed in current narrow |
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.
has: link
might not get displayed is the case, I think.
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 am able to send messages with link when has:link narrow is active.
static/js/message_util.js
Outdated
return $('<div>').append(message.content).find(`${tagName}:first`).length > 0; | ||
} | ||
|
||
exports.does_message_have_link = function (message) { |
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.
These functions can be better named as exports.message_has_link
, etc.
static/js/message_util.js
Outdated
@@ -16,6 +16,23 @@ function add_messages(messages, msg_list, opts) { | |||
return render_info; | |||
} | |||
|
|||
function does_message_content_have_html_tag(message, tagName) { | |||
// creating a virtual dom to check for html tag in message.content. | |||
return $('<div>').append(message.content).find(`${tagName}:first`).length > 0; |
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'm curious about GC related issues with this. I added a similar check in one of my PRs but I've a feeling JQuery might keep a reference to the created object internally and as a result we could end up with a lot of Query objects each time this function is called.
Do you know if that isn't the case here? I couldn't find anything relevant online so far.
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 write a quick jsfiddle and monitor it's memory usage to see if it's the case.
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.
https://github.com/jquery/jquery/blob/master/src/core/init.js
https://github.com/jquery/jquery/blob/master/src/core.js
I think it just return object and it should be garbage collected.
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 looks nice! The changes make sense, but I'm confused about the tests as they exist now. Maybe they could use some comments to explain what's the intention?
zrequire('Filter', 'js/filter'); | ||
|
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.
Accidentally removed this line?
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
frontend_tests/node_tests/filter.js
Outdated
@@ -715,6 +717,50 @@ run_test('predicate_basics', () => { | |||
display_recipient: [{id: steve.user_id}, {id: me.user_id}], | |||
})); | |||
assert(!predicate({type: 'stream'})); | |||
|
|||
const img_msg = { | |||
content: "<p><a href=\"\/user_uploads\/randompath\/test.jpeg\">test.jpeg<\/a><\/p>\n<div class=\"message_inline_image\"><a href=\"\/user_uploads\/randompath\/test.jpeg\" title=\"test.jpeg\"><img src=\"\/user_uploads\/randompath\/test.jpeg\"><\/a><\/div>", |
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 could use strings contained within single quotes or backticks to avoid the escaping here... unless it was actually simpler to use these from our markdown_test_cases.json
directly.
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 back-tick approach is better.
frontend_tests/node_tests/filter.js
Outdated
|
||
predicate = get_predicate([['has', 'link']]); | ||
let mockElem = $("<div>").append(link_msg.content); | ||
mockElem.set_find_results("a:first", [$("<a>")]); |
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'm confused; how are these tests working? What is calling find on a div
in the DOM to which you're appending these?
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.
Umm wait I will clean it up. I think I mixed up.
frontend_tests/node_tests/filter.js
Outdated
assert(!predicate(no_has_filter_matching_msg)); | ||
|
||
predicate = get_predicate([['has', 'attachment']]); | ||
mockElem = $("<div>").append(non_img_attachment_msg.content); |
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.
Is it intentional that you want to append to the existing JQuery object?
1cba481
to
3326c0f
Compare
3326c0f
to
a922885
Compare
@aero31aero I have pushed new changes. |
narrow_state.filter().has_operator('has') | ||
) { | ||
return; | ||
} |
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'd write the if statement with fewer lines
frontend_tests/node_tests/filter.js
Outdated
}; | ||
|
||
const non_img_attachment_msg = { | ||
content: `<p><a href="/user_uploads/randompath/attachemnt.ext">attachment.ext</a></p>`, |
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.
attachment is mispelled
frontend_tests/node_tests/filter.js
Outdated
$(link_msg.content).set_find_results(".message_inline_image", false); | ||
assert(!predicate(link_msg)); | ||
$(no_has_filter_matching_msg.content).set_find_results(".message_inline_image", false); | ||
assert(!predicate(no_has_filter_matching_msg)); |
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 this test might be more readable if saved the predicates like this:
check_has_link = get_predicate([['has', 'link']]);
...
And then setup 6 or so messages and just assertions like this:
assert(has_link(img_msg))
assert(has_attachment(img_msg))
assert(has_image(img_msg))
static/js/filter.js
Outdated
} else if (operand === 'attachment') { | ||
return message_util.message_has_attachment(message); | ||
} | ||
return false; // is:whatever returns true |
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.
Comment should use has
.
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.
and also say false, since that's what we're doing here :)
Posted a batch of comments; but this looks great otherwise! |
a922885
to
86a60ed
Compare
Prior to this commit has:link, has:attachment, has:image filter couldn't be applied locally and deferred filtering to web server. This commits make sure client filters all messages it can instead of completely deferring to the server and hence improve speed. A tradeoff is also made to turn off local echo for has: narrows as messages with link sent to has:link narrow were locally echoing to another narrow and not appearing in the active has:link narrow. Fixes: zulip#6186.
86a60ed
to
030c1a6
Compare
Re-run test by force pushing. |
I merged as 02ea52f, after reworking the local echo logic to feel more intuitive; take a look and let me know what you think. Thanks @thedeveloperr! |
@timabbott I want to understand more about the reason of local echo change. I mean it feels counter intuitive and logic more hidden. |
Oh, that was because |
Prior to this commit has:link, has:attachment, has:image
filter couldn't be applied locally and deferred filtering to
web server. This commits make sure client filters all messages
it can instead of completely deferring to the server and hence
improve speed.
A tradeoff is also made to turn off local echo for has: narrows
as messages with link sent to has:link narrow were locally echoing
to another narrow and not appearing in the active has:link narrow.
Fixes: #6186.
Testing Plan:
GIFs or Screenshots: