Due date: Thursday May 14, 11pm
Submit to: https://peer.crowdgrader.com/crowdgrader/venues/view_venue/4642
This homework asks you to implement a simple social site using Vue.js.
The assignment should enable users to log in, and then create posts:
The Post button will add the post, and the Cancel button displays again the list of posts, without adding the post.
Posts are displayed in reverse chronological order, and you can see posts by all users. Below each post is:
The behavior of the thumbs up-down is as follows. Say that a thumb is true if it is solid, and false if outline.
The thumbs are per user: my thumbs up and down are distinct from the ones of other users, and I can change mines only.
Thumbs, and posts, have to be written to the database, so that reloading the page preserves the state.
After (and only after) the above is implemented, make it so that when you hover over the thumbs-up-down area, you can see the list of users who liked or disliked a particular post. This should disappear when the mouse leaves the area, and it should be updated if you press on a thumb. As an example, Peter Pan would see:
And Luca de Alfaro would see:
Here is a video showing how the solution should look like.
You can also download the video (~35MB).
Your solution must:
Use this starter code: https://bitbucket.org/luca_de_alfaro/homework5_starter/src/master/
This will clone the starter code into "hw5":
git clone https://luca_de_alfaro@bitbucket.org/luca_de_alfaro/homework5_starter.git hw5
As you can see, the starter code contains:
models.py
. No change is needed to this file.templates/index.html
. This will save you all the time required to build the "look" of the site, so that you can focus on the code.controllers.py
.static/js/index.js
So, the only files you need to edit are:
controllers.py
static/js/index.js
templates/index.html
Add Post
I insert the post in the list of posts in javascript, then send the post to the server. A simpler solution would be to send the post to the server, and then, once that succeeds, reload the list of posts. Indeed, this may be better in case the network fails, as the user would know that the post has not been added. Look at the lecture on vue and at the related code for how to implement that.
Note that we do not need to add first and last names to the post table. There are first_name and last_name fields in the auth_user table (you can see it in the Dashboard, look at the database for your application), so you can do e.g.
r = db(db.auth_user.email == auth.current_user.get("email")).select().first()
name = r.first_name + " " + r.last_name if r is not None else "Unknown"
It is bad form to keep duplicated information in a database; if one wants to change their name from "Bob" to "Ada" there should be only one place to update, the auth_user table. You can read this documentation about the auth table, and you can also browse the code where the auth_user table is defined. The auth_user table has among others these fields: email
, first_name
, last_name
.
Delete Post
To decide whether to show the deletion button, compare the email of the logged-in user with that of the post owner, and show it only if they match.
If the user presses the button, delete the post from the list of posts, and let the server know that the post is deleted.
Thumbs
Study how I implemented star rating.
List of Likers and Dislikers
The events I used to detect hovering over the thumbs are mouseenter
and mouseleave
. For every post, I keep:
show_likers
flag indicating whether such list is to be displayed.The mouseenter
event sets show_likers
to true, and the mouseleave
event sets it to false. Also, the mouseenter
event triggers an AJAX call that loads from the server the list of likers and dislikers for the post. Remember to refresh this list when a user clicks on thumbs up/down.
If you want to be fancy and avoid too many server calls to load the likers and dislikers, add to each post a flag known_likers
, initially false, and load the likers/dislikers only when the flag is false; change the flag to true once the likers/dislikers to true after this. This avoids a lot of server calls as users move the mouse around the page.