Closed ksurya closed 10 years ago
Few things to fix before I look at the code:
Some suggestions:
I think that's it for now. After you fixed this (feel free to rebase to make history prettier with all these changes since I haven't looked at commits and code yet), I'll see if there's anything more and I will look at the code itself.
Sorry, I totally forgot about delete
and edit
features.. Its unusal but it happened! I added those features will push them soon. Regarding others things you mentioned
CommentModerators
User group who have moderate comment
permissions. Regarding the total number of flags for a commit - Sorry, it did not occur to me at the first place. As far as I know there is no such field in django that provides (have to look into docs again). The whole reason why I used a lightbox
for flag is that, I want to provide users to enter a message before they are flagging! I don't know if I will be able to do it during GSoC as I feel there are some more high priority issues :) Possibly, we can create a nice interface for moderators too by then.. more ideas popping up now.. didn't occur to my mind while writing proposal. However, this is a something I am anyway going to do after the GSoC period..
envelope-icon
pointing to comments list of every submissionnotification
mechanism.. some users want to get email, some want to see as a simple notification on the website. I think we need to build notification
feature first for the site users and moderators in proper way, then, go on with this stuff.. And this is again big work to put in GSoC timeline since its not presentThe remaining stuff like hightlight preview, link to user profile, etc stuff, I will fix them and push!
Overall, this looks very good to me.
There's one issue though: when does the is_public
flag on the comments turn on?
It seems I can write comments fine, but they are not marked public. Perhaps this should be done when the comment is created?
A final thing (not for this PR): scipy-central needs tests. Testing all the feature set manually is getting somewhat cumbersome.
It's possible to write tests using the Django test framework that emulate using the site with a browser. Doesn't run JS, but you can emulate the AJAX calls directly. Having a number of such tests for core functionalities of the site would be useful for the long term.
@lomegor I have made all the changes - can you please look into it. Please let me know if I forgot any! @pv
Hi: some remaining issues
Delete
and Flag
buttons still stay visible after they are pressed.Otherwise, seems to work nicely!
Thanks for pointing out, I didn't observe it at all! I just checked it and found that
$('#spc-comment-list').load(' ' + '#spc-comment-list');
to reload comment list is causing it surprisingly.
I will hide those delete
and flag
buttons upon successful submission
@lomegor its fixed now. Instead of loading the comment list again after every edit, I am just editing the comment on the client side itself (after receiving the data from server). I think this is simplest possible way..
The 'delete' and 'flag' buttons hide after successful form submission! In case of 'edit', I didn't do this because, user might want to edit it again and again!!
Cool. I'm going to take a look at all of thus later. On 17 Jul 2013 21:39, "Surya Kasturi" notifications@github.com wrote:
@lomegor https://github.com/lomegor its fixed now. Instead of loading the comment list again after every edit, I am just editing the comment on the client side itself (after receiving the data from server). I think this is simplest possible way..
— Reply to this email directly or view it on GitHubhttps://github.com/scipy/SciPyCentral/pull/131#issuecomment-21143034 .
Things to fix (still haven't looked at the code since it can change a lot):
Few things to fix before I look at the code:
I think that's it, but there may be other things I'm missing. I may take a look at the code while you fix these things, so try not to rebase too much. If you do end up rebasing to make the commit history look better, let me know.
Another thing to keep in mind because it's something we should do is that after login or logout, user should be redirected to the page they were in. Also, the sidebar still says Copyrights which reads weird. This is not something to do in this PR, but you can open a new one for both I believe if you have the time.
I have to check the other things. Thanks!
@lomegor the changes have been made now! please take a look. The thumbs PR is also ready!
I'm going to look at the commits now and may ask you to rebase them or change the message. When fixing these issues, take into consideration that you can rebase and try to make the commit history look pretty. Also, when you have fixed these issues, try to go number by number and test everything I told you again; last time there were at least 4 bugs that weren't fixed, and this time there are 5 bugs that still exist from my past correction.
Comments about the commits:
I think that's it! After you've fixed these things, I'll take a look at the code (although I may take a look sooner if I have time).
Okay. quick fixes.
That image is from our repository itself. But the current update is a scaled version..
@ksurya Did you read my other comment about the bugs? I'm going to copy again, because I'm not seeing any of those bugs solved.
I'm going to look at the commits now and may ask you to rebase them or change the message. When fixing these issues, take into consideration that you can rebase and try to make the commit history look pretty. Also, when you have fixed these issues, try to go number by number and test everything I told you again; last time there were at least 4 bugs that weren't fixed, and this time there are 5 bugs that still exist from my past correction.
@lomegor
by suryak on July 7, 2013, 3:06 a.m.
. the user name is still an hyperlink
I think that's about it for the bugs. I'm going to look at the code. Remember to fix 1..3
So, as I say, I'm going to comment a bit about how to use Javascript and jQuery when you have this amount of functions and code and everything. I'll try to explain everything, but ask me any question if you want to know more. Using these ideas, I'll need you to recreate the Javascript code. Also, these are ordered by importance; some of them you should always keep in mind when writing Javascript.
Don't clutter the global namespace! Use a closure for your code. When you define a variable in Javascript outside of a function, or class, or whatever, you are creating a property of the global window
object. So if I do var a = 'b'
in the begining of a script, window.a
will now contain 'b' and every piece of code will be able to access it; outside of any function if you use a
, from now on it will mean window.a
and everyone can change it. This of course means that a lot of code may have problems because they use a variable with the same name.
The most direct case I've seen it happen in your code is when you use variables without a prepending var
. For example, here. You can try it yourself. Post a comment, and you will see in the developer Console that you now have a variable window.formData
with exactly what you sent. This also may happen in other parts of your code, so check it out.
There's a more hidden way in which this can happen. As you probably know by now, functions in Javascript are first class citizens. This means (among many things) that when you declare a function you are declaring a variable itself. So, when you do function postComment
, you are now creating window.postComment
which is a function. Anyone can call window.postComment
, and anyone can change it. So, if for some mistake you create a variable called postComment
in the global namespace, you will lose the function.
It's important to note that this isn't a security issue. Since Javascript runs in the client, you can never ever trust it, even if you are declaring variables inside a closure. But, it's important to keep our code bug free, since using the global namespace can cause undesirable and unexpected situations.
So, I'm not sure if you know what a closure is, but you can read it here although it may be difficult to understand. The simple idea is that functions in Javascript not only reference the code that is inside the function, but also the environment in which they were created. For example: var a = 1; function b() { console.log(a) }; b()
will log into the console 1. It's a bit like if everything was a method inside an object, but with more difficult ideas that we may get to later.
How do you do a closure in the script? Easy! Just have all the code you are doing surrounded by a self executing anonymous function, i.e. (function() { code here })()
. The problem now is that those variables don't exist in the window
object, so you can't use inline Javascript (like onclick
in the element to call them). We'll get on how we can solve this issue later. Let's now focus on an important closure for jQuery.
As I've told you, variables in Javascript are all global, this includes $
, so when you are using it, you are never sure what variable you are calling. This gets more tricky, when you start to use other frameworks together. For example, Prototype, I believe, also uses the $
variable as a function. So how can you be sure that the $
you are using (really just window.$
) is jQuery? Simple, just pass the jQuery object to your anonymous function and call it $
.
So, instead of only having an anonymous closure, you are now making us of it by reassuring you that you are using jQuery when you use the $
(which let's be honest, it's much simpler that the jQuery object window.jQuery
). The anonymous closure should then be (function($) { code here })(window.jQuery);
.
Almost everything in jQuery should run when the document is ready. This solves a lot of small issues. For example, let's say I'm using a really slow computer with a horrible browser; the page takes 3 minutes to load completely. If I click to submit a post, but the whole page isn't ready, maybe the elements you need to submit the form do not exist yet. You will probably get an undefined behavior, since some of the data will be empty.
It's really easy to solve this issue. Just have everything in your code that is dependent on DOM elements to only load when the document is ready. jQuery provides a great of doing this $(document).ready(function() { code here });
. The code that goes inside of that function will run when the document has loaded completely.
So, to give you and idea, we now have:
(function($) {
$(document).ready(function() {
// code here
});
)(window.jQuery);
Cache everything. You never know what machine the client is running, but it's always safe to assume that it's 10 times worse than yours (and you should consider mobile, too). I think Javascript is one of the few languages where pre-emptively optimizing is important; in almost all other languages you should test things before trying to make them faster. in Javascript, you should assume your code will run slowly.
What does this mean? Well, as I said in a few comments in the diff, it means that you should avoid calling $('selector')
every time you need an object from the DOM. Especially when the object does not ever change. You should try to initialize variables before using functions that need those elements, so you don't need to select elements every time. This isn't so important with your selectors (since they are all based on ids and those are fast as hell), but it's a good practice to keep.
The code is getting more reasonable now, and it would look something like this:
(function($) {
$(document).ready(function() {
// Initialize variables here, e.g:
// var editCommentText = $('#edit-comment');
// code here
});
)(window.jQuery);
Since we are inside of the document ready function, you know that those elements will exist (unless they are created dynamically).
Abuse events. We just saw some kind of use of events with the ready
function for the document, but we should use them as much as we can. Especially when the app gets really big (which is not the case here), even relying on your own events is helpful to keep code organized, pretty and stable.
I suppose you already know what events
are, but just in case, they are things that happen that you can listen to. So, for example, when the document is ready, it fires an event of type ready
, and since you are listening to it (by using $(document).ready
, your code will execute.
Events solve one problem we had earlier: inline Javascript. Instead of using the onclick argument in the elements, you just do $(selector).on('click', function() { code here});
, and the code will execute every time an element matching the selector gets clicked on. This makes the code easier to follow. These functions should be inside the document ready function, so you now have:
(function($) {
$(document).ready(function() {
// Initialize variables here, e.g:
// var editCommentText = $('#edit-comment');
// code here (binding events, etc, e.g.:
// $('#edit-comment').on('click', function() {
// edit comment
// });
});
)(window.jQuery);
Remember that functions are first-class citizens. So you can pass a function as an argument or just have a general function for errors. You can even set your own event for errors and have a listener to it just in case. Either way, just remember that you can use functions as you use variables (you can even do var functionname = function() {}
), although don't abuse this too much.
The only problem you now face is how to keep track of which comment is being edited for example. But, with this you don't even have to declare any function now, since they are almost all based on events. Including the one to clear the modal
, because it can listen on the show
event of the bootstrap modal
(look it up in Bootstrap documentation).
I think that's about it for general recommendations. I must be forgetting a lot, but I will get to it when I see it :) The problem you now have (tracking which comment is being edited, deleted or flagged) can be solved in many different ones. One way for example is using jQuery data
function to attach objects or variables to elements. Or just using HTML5 data-
attributes in elements to keep score of what comment an element is referring to. Or you can have a "global" (global within your closure) variable set every time a comment starts being edited. Or you can use a jQuery history plugin to keep track of what you are doing, and use that as events. There are many many solutions; just think what you like best, and I will probably shout at you later for not selecting the one I like :)
If that's the case you shouldn't probably be using ids. ids are for elements that are unique or that need to be uniquely identified or that work in a unique way. A class is for a group of items that look similar or work similar or share some properties. You should probably be using a class in that case, which would be
$('.edit-coment').on('click', function() {
On 30 July 2013 10:14, Surya Kasturi notifications@github.com wrote:
@lomegor https://github.com/lomegor Thanks a lot for your comment above! Everything sounds good but I still see the tracking of comments problem! That is the reason why I did not use document.ready() before.
In the above mentioned example code $('#edit-comment').on('click', function() {
Since we have many comments, we need to have comment-id value before the onclick event. $('#edit-comment{{comment.id}}").on('click', function() {
There would be many comments and many edit, flag, delete links, even though we use HTML5 data- attribute (for instance), we need to have element Id to get them..
— Reply to this email directly or view it on GitHubhttps://github.com/scipy/SciPyCentral/pull/131#issuecomment-21778580 .
@ksurya Please re read my comment and tell me if you didn't understand anything. I need you to fix the code before I take a look at it, because right now is even messier. Everything you write in Javascript should be inside the closure and the document.ready, and there should only be one of them (unless for some reason it's absolutely necessary to have code in different files, which I don't think it is). Otherwise, as I told you, you are pollutin the window
objects with your variables. So, it should be like this:
(function($) {
$(document).ready(function() {
// ALL CODE SHOULD BE HERE
});
})(window.jQuery);
There's no reason in this code to have more than one closure.
Some more errors I noticed now:
I think that's it for that.
There's some comments that you may have missed because they are not fixed nor do they have a response:
https://github.com/scipy/SciPyCentral/pull/131/files#L1R50
https://github.com/scipy/SciPyCentral/pull/131/files#L10R9
https://github.com/scipy/SciPyCentral/pull/131/files#L10R12
https://github.com/scipy/SciPyCentral/pull/131/files#L15R26
https://github.com/scipy/SciPyCentral/pull/131/files#L25R46
https://github.com/scipy/SciPyCentral/pull/131/files#L25R50
https://github.com/scipy/SciPyCentral/pull/131/files#L25R100
I added some comments on the diff. I'm going to repeat things that I saw in all the code that I think are important, and that you should look for in the code and fix:
$(selector)
every time you call the function one one time at the beginning would suffice.$(selector)
every time you need them. Just one time at the beginning of the function should be OK.$(selector)
at the beginning of the function since they are static (only the content changes).$
to variables which are jQuery objects.I think that's about it, but read my comments carefully and look at the diff, because some of them may apply in more than one place.
@ksurya You need to pay more attention to the comments we leave you. You missed at least 7 comments and you also committed mistakes I've already talked about (like having constant variables). I don't know how you are doing it right now, but you should go over all the comments in the Discussion, and after that, you should go to the Diff and read all the comments there. Even after you think you've fixed everything you should go over every comment again to be sure; you are missing quite a lot of things. If you don't understand something or if you are unsure, do ask.
Also, you are having quite a lot of bugs that can be fixed with simple testing. After fixing things, you should at least spend one hour testing different things until somethings breaks (something will probably break). Think of every possible way users will access the feature and do the most awful thinks you can think of (for example, posting a comment, deleting it, clicking edit on another comment, flagging, posting new comment, edit it, flag it, edit it, delete it). You should try these things both logged in and logged out, with the same user and with a different user, etc. Try almost every possible thing you can think of.
Thanks
Things still needed to be fixed! You need to pay more attention. I'm going to bold problems that existed in previous versions and you haven't fixed.
@ksurya, it seems I need to say it again. You need to do all these things:
You are making a lot of mistakes that we've already talked about. Once you finish this, you should go to the reputation branch, and update everything to fix all the mistakes we've already talked about. I'm not going to look at the reputation branch if it's going to have a lot of the same errors than this one.
Also, run pylint!
This looks close to finished now, @lomegor?
I'm going to take a look tomorrow On 17 Aug 2013 14:25, "Pauli Virtanen" notifications@github.com wrote:
This looks close to finished now, @lomegor https://github.com/lomegor?
— Reply to this email directly or view it on GitHubhttps://github.com/scipy/SciPyCentral/pull/131#issuecomment-22811818 .
Small things to fix...
I think that's about it. They are all small stuff, but some are a bit important. For example the error when posting on the preview tab.
Overall, very good job! Keep working like this and next time I'll look at this it will be ready to merge!
Don't get discouraged by these errors; they are relatively small compared to all you have fixed. Thanks.
<div>
with <button>
for submit buttons which enable tabindex. This should fix this min-height
had to be provided along with some paddingtime.sleep()
to delay on server side, and I could see the images on the both sides. Fixed it anyway@pv If it's OK with you, I think we can now merge this. Thanks, @ksurya!
Thanks! Merged.
Thanks!
Comments for SciPy Central built over
django.contrib.comments
CommentModerators
user groupNote:
Thumbs
branch. It has to be updated once this is merged!