For the duration of this course, you will work in teams to develop
a microblogging and social networking web application based
loosely around Twitter. In this second project, you will work
individually to add dynamic content to your user interface from
Project 1. You will gain experience programming in JavaScript,
manipulating the DOM, and using asynchronous fetch
.
SlugFest is said to be the next hit social media site1—you just have to create it first! Members can post short messages ("slimes") for their followers to read. Members can also "favorite" slimes that they like or even "reslime" so that the post shows up on their own profile. Additionally, this is a social site, so it is possible to reply to slimes creating a "slime trail" conversation. If these features sound familiar, that's because they are based off of those supported by a popular microblogging and social media site.
You will be given a collection of JSON files containing the information for SlugFest to display. It is your job to recreate many of the pages from Project 1 using this information.
611fcaf640148d94e2a469c7
and its replies, and
You are provided with the profile pictures for users of SlugFest. Additionally, there are JSON files in an API (Application Programming Interface) directory. These JSON files contain structured data representing each slime as well as each user account. Skeleton HTML files are also provided, should you wish to use them (you may also use your own code).
Thes files may be downloaded here. An older copy (with different user information) is available here. The contents of this file is:
unzip -l p2_assets.zip
(out)Archive: p2_assets.zip
(out)Length Date Time Name
(out)--------- ---------- ----- ----
(out) 0 10-26-2021 15:13 starter-code/
(out) 0 10-26-2021 14:46 starter-code/skeletons/
(out) 3809 10-26-2021 14:46 starter-code/skeletons/feed.html
(out) 5615 10-26-2021 14:52 starter-code/skeletons/profile.html
(out) 2940 10-26-2021 14:53 starter-code/skeletons/notifications.html
(out) 3045 10-26-2021 14:52 starter-code/skeletons/slime.html
(out) 0 10-26-2021 15:13 starter-code/api/
(out) 0 10-26-2021 15:00 starter-code/api/favorites/
(out) 1011 10-26-2021 15:00 starter-code/api/favorites/ltorrey.json
(out) 2421 10-26-2021 15:00 starter-code/api/favorites/ed.json
(out) 2118 10-26-2021 14:38 starter-code/api/favorites/list.json
(out) 3 10-26-2021 14:59 starter-code/api/favorites/choongsool.json
(out) 2118 10-26-2021 15:00 starter-code/api/favorites/kevinaangstadt.json
(out) 0 10-26-2021 13:25 starter-code/api/user/
(out) 0 10-26-2021 13:26 starter-code/api/user/get/
(out) 570 10-26-2021 14:49 starter-code/api/user/get/ltorrey.json
(out) 494 10-26-2021 14:49 starter-code/api/user/get/ed.json
(out) 452 10-26-2021 14:49 starter-code/api/user/get/choongsool.json
(out) 578 10-26-2021 14:48 starter-code/api/user/get/kevinaangstadt.json
(out) 0 10-26-2021 15:13 starter-code/api/statuses/
(out) 0 10-26-2021 15:13 starter-code/api/statuses/replies/
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175ccd3969d515951edefac.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175cb4a969d515951edefa9.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175ccf1969d515951edefaf.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175ca7a969d515951edefa7.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175ccbe969d515951edefaa.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175ccfa969d515951edefb0.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175ccde969d515951edefad.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175cce8969d515951edefae.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175ccc7969d515951edefab.json
(out) 1147 10-26-2021 14:36 starter-code/api/statuses/replies/611fcaf640148d94e2a469c7.json
(out) 1278 10-26-2021 14:36 starter-code/api/statuses/replies/6175c92c969d515951edefa3.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175c9a2969d515951edefa4.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175cb11969d515951edefa8.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175c9e3969d515951edefa5.json
(out) 3 10-26-2021 14:36 starter-code/api/statuses/replies/6175ca53969d515951edefa6.json
(out) 0 10-26-2021 14:18 starter-code/api/statuses/show/
(out) 884 10-26-2021 14:18 starter-code/api/statuses/show/6175ccd3969d515951edefac.json
(out) 1192 10-26-2021 14:18 starter-code/api/statuses/show/6175cb4a969d515951edefa9.json
(out) 885 10-26-2021 14:18 starter-code/api/statuses/show/6175ccf1969d515951edefaf.json
(out) 1973 10-26-2021 14:18 starter-code/api/statuses/show/6175ca7a969d515951edefa7.json
(out) 884 10-26-2021 14:18 starter-code/api/statuses/show/6175ccbe969d515951edefaa.json
(out) 884 10-26-2021 14:18 starter-code/api/statuses/show/6175ccfa969d515951edefb0.json
(out) 885 10-26-2021 14:18 starter-code/api/statuses/show/6175ccde969d515951edefad.json
(out) 884 10-26-2021 14:18 starter-code/api/statuses/show/6175cce8969d515951edefae.json
(out) 885 10-26-2021 14:18 starter-code/api/statuses/show/6175ccc7969d515951edefab.json
(out) 1028 10-26-2021 14:18 starter-code/api/statuses/show/611fcaf640148d94e2a469c7.json
(out) 1063 10-26-2021 14:18 starter-code/api/statuses/show/6175c92c969d515951edefa3.json
(out) 1890 10-26-2021 14:18 starter-code/api/statuses/show/6175c9a2969d515951edefa4.json
(out) 2022 10-26-2021 14:18 starter-code/api/statuses/show/6175cb11969d515951edefa8.json
(out) 935 10-26-2021 14:18 starter-code/api/statuses/show/6175c9e3969d515951edefa5.json
(out) 1064 10-26-2021 14:18 starter-code/api/statuses/show/6175ca53969d515951edefa6.json
(out) 0 10-26-2021 13:30 starter-code/api/statuses/user_timeline/
(out) 3348 10-26-2021 13:30 starter-code/api/statuses/user_timeline/ltorrey.json
(out) 4317 10-26-2021 13:30 starter-code/api/statuses/user_timeline/ed.json
(out) 7006 10-26-2021 13:30 starter-code/api/statuses/user_timeline/choongsool.json
(out) 4683 10-26-2021 13:29 starter-code/api/statuses/user_timeline/kevinaangstadt.json
(out) 5418 10-26-2021 13:25 starter-code/api/statuses/activity.json
(out) 19345 10-26-2021 13:24 starter-code/api/statuses/home_timeline.json
(out) 0 10-26-2021 15:13 starter-code/assets/
(out) 0 10-11-2021 13:27 starter-code/assets/profile/
(out) 249750 09-05-2021 14:17 starter-code/assets/profile/kevin.jpeg
(out) 79031 09-05-2021 14:20 starter-code/assets/profile/choong-soo.png
(out) 75662 09-05-2021 14:17 starter-code/assets/profile/ed.png
(out) 18900 09-05-2021 14:18 starter-code/assets/profile/lisa.jpeg
(out)--------- -------
(out) 512456 65 files
As befitting a 300-level elective, this assignment is fairly open-ended. There is no "one true path" to creating and styling the required pages. Thus, this project requires you to tap your inner creativity and problem-solving.
Under-specification is fairly indicative of the real world. Clients will often expect you to "read their mind" to deliver a product that meets their needs. This can definitely be frustrating at times, but it is also a good lesson to learn early. It will help you be a high-quality developer who gains a positive reputation with clients.
A keen eye for detail is also key here. While there is textual description of each page provided, taking a close look at the provided images for styling and inferring withheld information can help you decide how to proceed.
As this is an upper-level course, you may use outside references to complete this assignment. Be sure to keep a running list of citations as you work on this project.
You will most certainly want to split your code into multiple JavaScript files. A good first step is to create a file for generating the HTML needed to display slimes. Note that you may need separate functions for slimes on "standard" pages vs. the "slime trail" page. One possible function interface is shown below.
/**
* Create a Slime DOM and return it
* @param slimeData {object} all of the data needed to create a slime
* @return a DOM Element object for the slime
*/
function createSlime(slimeData) {
}
There are many opportunities for code reuse across this project. One such place is for generating user profile pages. Thus, only write this code once. Write this code as a function that receives a username as a parameter so that it can be used for all profile pages. Then, have a small piece of JavaScript on each individual user profile page that calls this function with the appropriate username after the page has loaded.
To assist your code reuse, avoid the temptation of combining code to process and manipulate JSON data with code to produce and manipluate DOM nodes. This can be very tempting, but it reduces your ability to reuse code. Write some functions that fetch and process JSON to produce JavaScript objects. Write different functions that take an object and produce a DOM node. You might even consider writing separate functions that take DOM nodes and insert them at specific selectors on a page.
Be sure to ask lots of questions as you work on this project. Questions about the desired behavior are likely to receive more expressive answers than direct questions about the reference implementation (your clients won't have a reference impelmentation).
Because there will be a nontrivial amount of code for this project,
make a separate folder to hold all of this code. Typically, this
folder will be named js
.
You may want to look back at the Project 1 specification for styling hints.
Be sure that you are submitting to the correct assignment on Gradescope! Further, be sure to make sure that you submit all required files. Don't wait until the last minute to submit (you can resubmit up to the deadline).
Submit the following:
*.html
: all HTML files needed for your pages
*.js
: all JavaScript files needed for your pages
*.css
: any additional CSS files you may have needed.
I will view your files by creating a small Python webserver as we have done in class:
python3 -m http.server
Thus, make sure that your files are submitted with a folder structure identical to your development machine. You will likely want to use relative URIs for assets.
P2 Grading (out of 100 points):
fetch
API
async
/await
)
Below is a description of some of the API data provided in the assets for this project. Note that you will likely have to look through this data in more detail, but use this as a starting place for finding the right files.
As a side note, this JSON file structure is based very closely on the Twitter v1.1 API to give you a real sense of implementing a real-world application. Some aspects of the file layout have been modified to work better with this project.
Lists of each user's favorited slimes are stored in
/api/favorites/<username>.json
. These are
sorted in reverse order (with the newest first). Note that the
associated slime IDs are also available through the User API for
individual access through the Statuses API.
Information about each user is provided in
/api/user/get/<username>.json
. These JSON files
contain information about each user account on SlugFest.
The statuses API provides information about status updates (aka slimes). There are several relevant pieces, ranging from timelines to individual slimes.
Timelines (sorted lists of slimes) for each user are provided in
/api/statuses/user_timeline/<username>.json
.
The main timlines (the home feed page) is provided in
/api/statues/home_timeline.json
Individual slimes are available in
/api/statuses/show/<slime_id>.json
. A slime ID
is a unique string associated with each slime when it is posted.
It is also possible to see the slimes that are in reply to another
slime. This information is stored in
/api/statuses/replies/<slime_id>.json
, where a
slime ID is defined as above.
Slime activity (aka notifications) are stored in
/api/statuses/activity.json
. To simplify coding,
this will only show reslimes and replies (we are dropping
favorites from notifications).
The initial concept for this project is borrowed from an assignment designed by Andrew DeOrio at the University of Michigan.
1By your professor