Assignment 11
Due
Submitting your homework
We are going to use Github Classroom for this assignment. You need to have an account on GitHub and be logged in. Authorize Github Classroom here and accept the assignment, then follow the instructions there. Please follow the structure and naming of the starter repo, though you can add any additional files if you need them.
To submit the assignment, please visit Canvas
and submit the URL to your final commit that you want us to grade.
A commit URL looks like https://github.com/designftw-YEAR/hw11-username/commit/b59f14ba05869b3067724aa6d2006667a54c8e7d.
You can submit as many times as you want.
This is important. Your homework is not submitted and is accruing slack hours until you do this!
To make sure your homework is graded correctly, please follow the following:
- Please make sure each of your exercise directories are self contained, i.e. that you don't reference any files outside of the directory (e.g. from your repo root or other exercises). While having a common assets directory for all your exercises might be a good idea in general, we extract each exercise directory separately (as it may be graded by different people), and that will result in your pages not working correctly.
- Do not use root-relative URLs (URLs that start with
/) or absolutelocalhostURLs, as these require the grader to run a local server at a specific directory within your repo. If for some reason you cannot avoid it, please document it in a README otherwise links may be broken for whomever is grading your homework.
If you submit after the deadline, it will count towards your slack hours.
AI Policy
You may use AI for any of the implementations in this assignment. The writeups must be your own.
We have created a markdown "skill" file, graffiti.md, which you can download and feed to your AI agent so that it learns what Graffiti functions it can (and cannot) use.
Exercise 1: Setup Github Pages (10%)
As you work towards completing your chat app, it will be useful to have a live version of the app that you can visit on other devices or share with your friends to test. We will be using Github pages to host your app, which is free and your app will update whenever you push new code to Github.
Follow the Github Pages instructions here.
You will need to create a new public repository for your chat app (separate from the homework repository), push your chat app code to that repository, and then enable Github pages for that repository.
Once done, you should be able to visit your app at https://<your-github-username>.github.io/<your-repo-name>/.
Note that after the class if you want to continue using your chat app, you could choose to buy a custom domain which you can use instead of Github's domain.
Deliverable: A basic chat-app/index.html file that includes
two links, one to your chat app source code, and one to your
chat app hosted on Github pages.
Exercise 2: Add client-side routing to your chat app (30%)
Per this week's lecture on single page applications and this week's studio, you will be implementing client-side routing in your app. This should make it possible to build your chat app as one unified application---which is a useful system model for implementation and performance---while still providing an intuitive user model of your app being a website with multiple pages, each of which has its own URL.
Your app should include at least three routes, and one route should be a dyanmic route like the "chat/:chatId" route in studio. Examples of routes you could use include:
| Page name | Example routes |
|---|---|
| homepage | / or /home |
| login page | / or /login |
| about page | /about |
| profile page | /profile/:actor |
| profile editor page | /profile/edit |
| chat page | /chat/:chatId |
| chat subpages | /chat/:chatId/media, /chat/:chatId/pinned, /chat/:chatId/search, /chat/:chatId/thread/:threadId |
| new chat page | /newchat |
| message composition page | /compose |
| settings page | /settings |
| contacts page | /contacts |
| explore page | /explore |
| friends page | /friends |
| drafts page | /drafts |
| help page | /help |
We suggest you finish studio 11 and build off of the studio 11 starter code which sets up Vue Router.
Deliverable: Your chat app linked in chat-app/index.html (same deliverable as Exercise 1) and a brief description of your routes in routes/index.html
Exercise 3: Add a component to your chat app (30%)
Setting up client side routing in exercise 2 involves creating components that represent entire pages. However, components can also be used for more granular features that can be reused within your app. Breaking out features into components will make your code easier to manage and reason about as it gets more complex.
We want you to add at least one such granular component to your app. This component must appear at least twice within your app (it is fine if it only appears once in your code due to the use of a v-for loop). Make a short writeup describing where the component is used and how it works.
Some examples of features that are good candidates for componentization include:
- A "message" component that displays a message in a bubble with a username/timestamp/etc.
- A "reply" component which could be recursively for threaded replies.
- A "like" or "reaction" component for reacting to different messages.
- A "pin" button to pin a message to the top of a chat
- A button to "friend" a user that can be used on their profile or within a chat
- A "user" component to display the user's chosen name and profile avatar
You are allowed to turn a feature you already developed into a dedicated component.
As with exercise 2, see the studio 11 starter code for component boiler plate code.
Deliverable: Your chat app linked in chat-app/index.html (same deliverable as Exercise 1) and your writeup in component/index.html.
Exercise 4: Adding a new feature (30%)
Exercises 1, 2, and 3 are largely about restructuring your code. We want to make sure you are also making progress on your design. For context, you have three homeworks including this one to complete your chat app. Since you started your chat app last week, your work this week is roughly the "halfway point".
This week, make sure you add at least one new feature to your chat app that builds toward your unique design. It is fine if this overlaps with the component/routing exercises, but the feature cannnot be one that was in your submission last week.
As part of your submission you should describe a "user story" that involves your new feature. You should briefly describe a hypothetical user and some task they want to do. Then you should describe the series of steps that the user takes to complete that task, starting from "They open the chat app".
As with your user testing, your high-level task must be non-trivial and should not reference your specific UI. For example, your task for the user might be to "find a message they sent last week to their friend". It should not be for the user to "use the filter feature to query messages by date" - that might be a step they take to complete a task but not their goal itself.
We will be evaluating this exercise based on the usability of the steps described in the user story. We will consider learnability, efficiency, safety, and graphic design. Therefore, the app should feel "complete" within the steps laid out in the story. However, your app can still have incomplete, missing, or placeholder features outside of the user story.
Deliverable: Your chat app linked in chat-app/index.html (same deliverable as Exercise 1) and a write up briefly describing your new feature along with your user story in feature/index.html.
Tip: Uploading files
Some of you may want to add features that involve uploading large files (images, videos, audio, PDFs, etc.). For performance reasons, there is a limit on how large Graffiti objects created with graffiti.post can be. Therefore there is a seperate API for uploading "media":
Media has a max size of 25Mb, which should be fine for most images. For video, you may need to set size limits or compress the video (ask AI how to do this).
The first thing you need to do to upload media is use the browser-native File API to allow the user to select a file from a file picker and store in (local) memory. This can be done with something like:
<!-- template -->
<input type="file" @change="handleFileSelect" accept="image/*">
// setup
const selectedFile = ref(null)
function handleFileSelect(event) {
const file = event.target.files[0];
if (file) {
selectedFile.value = file;
}
}
Note that the accept attribute can be used to filter for certain types of files. Here we are accepting all images. You could also accept video (video/*), audio (audio/*), text (text/*), pdf (application/pdf), etc. See here for a list of all "MIME types".
Then you can upload the file with graffiti.postMedia. Importantly, media cannot be assigned to channels so it cannot be "discover"ed like other Graffiti objects. Instead, a link to the media will need to be included in another Graffiti object. For example, to create a profile with a profile picture:
async function createProfile(session) {
if (!selectedFile.value) {
return alert("No profile picture!")
}
// 1. Upload the picture
const pictureUrl = await graffiti.postMedia({
data: selectedFile.value
}, session);
// 2. Post a profile object including a link to the picture
await graffiti.post({
channels: [session.actor],
value: {
name: "My Full Name",
icon: pictureUrl,
describes: session.actor
}
}, session);
}
In your app, there is a Graffiti component, GraffitiGetMedia, which you can use to display the media, which will correctly display most common types:
<graffiti-get-media
:url="profile.value.icon"
:accept="{ types: ['image/*'] }"
></graffiti-get-media>
Alternatively, if you want control over the media you could do:
<graffiti-get-media
v-slot="{ media }"
:url="profile.value.icon"
:accept="{ types: ['image/*'] }"
>
<img :src="media.dataUrl"/>
</graffiti-get-media>
or use it in your setup with useGraffitiGetMedia:
const { media } = useGraffitiGetMedia(
profile.value.icon,
{ types: ['image/*'] }
);
const blob = media.data; // The raw data
Exercise N: HW11 feedback
Since this is a new class, we need your constructive feedback about every aspect of it: lectures, homeworks, labs etc.
Please fill in your feedback about HW11 in this form. You can edit it as many times as you like until the survey closes (48 hours after the homework deadline). Since this is part of your participation grade, it does not affect your slack hours, but failing to submit the form on time, could result in a lower participation grade.