Skip to content
This repository has been archived by the owner on Jan 14, 2024. It is now read-only.

Commit

Permalink
Join link (#145)
Browse files Browse the repository at this point in the history
* Fix broken display of answers history

* Add click to copy link

* Register user when loading play page

* Document animal alias process
  • Loading branch information
aroquev00 committed Sep 10, 2020
1 parent 39fc9ea commit d8b8659
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 34 deletions.
22 changes: 17 additions & 5 deletions src/main/java/com/google/sps/daos/DatabaseUserDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.google.cloud.firestore.DocumentReference;
import com.google.cloud.firestore.DocumentSnapshot;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.WriteResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthException;
import com.google.firebase.auth.FirebaseToken;
Expand Down Expand Up @@ -116,8 +117,10 @@ public void createIfNotExists(String idToken) {

}

// Register a user in a gameInstance and return its newly assigned animal alias
// If user is already registered, just return the animal alias that was already assigned before
@Override
public void joinGameInstance(String idToken, String gameInstanceId) {
public String joinGameInstance(String idToken, String gameInstanceId) {
FirebaseToken decodedToken = null;
String userId = null;

Expand All @@ -136,12 +139,17 @@ public void joinGameInstance(String idToken, String gameInstanceId) {

ApiFuture<DocumentSnapshot> UserInGameInstanceFuture = userInGameInstanceDocRef.get();

String animal = "";

try {
DocumentSnapshot document = UserInGameInstanceFuture.get();
if (!document.exists()) {
int numberOfStudent = addOneToMembersCounter(gameInstanceDocRef);
registerUserInGameInstance(userInGameInstanceDocRef, userId, getAnimal(numberOfStudent));
}
animal = getAnimal(numberOfStudent);
registerUserInGameInstance(userInGameInstanceDocRef, userId, animal);
} else {
animal = (String) document.getData().get("alias");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Expand All @@ -153,6 +161,8 @@ public void joinGameInstance(String idToken, String gameInstanceId) {
// Add the active GameInstance to the User's entry in "Users" collection
firestoreDb.collection("users").document(userId).update("activeGameInstanceId", gameInstanceId);

// Return the animal that was assigned to the user
return animal;
}


Expand All @@ -165,15 +175,17 @@ private void initUser(String userId) {
}


private void registerUserInGameInstance(DocumentReference userInGameInstanceDocRef, String userId, String animal) {
private void registerUserInGameInstance(DocumentReference userInGameInstanceDocRef, String userId, String animal)
throws InterruptedException, ExecutionException {
Map<String, Object> docData = new HashMap<>();
docData.put("points", 0);
docData.put("numberAnswered", 0);
docData.put("numberCorrect", 0);
docData.put("numberWrong", 0);
docData.put("alias", animal);

userInGameInstanceDocRef.set(docData);
ApiFuture<WriteResult> future = userInGameInstanceDocRef.set(docData);
future.get();
}

private int addOneToMembersCounter(DocumentReference gameInstanceDocRef)
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/google/sps/daos/UserDao.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.google.sps.daos;

public interface UserDao {
public void joinGameInstance(String idToken, String gameInstanceId);

// Register a user in a gameInstance and return its newly assigned animal alias
// If user is already registered, just return the animal alias that was already assigned before
public String joinGameInstance(String idToken, String gameInstanceId);

public void createIfNotExists(String idToken);

}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,24 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr

UserDao dao = (UserDao) this.getServletContext().getAttribute("userDao");

dao.joinGameInstance(jsonObj.get("idToken").getAsString(), jsonObj.get("gameInstanceId").getAsString());
// Register a user in a gameInstance and get its newly assigned animal alias to return it to the client
// If user is already registered, just get the animal alias that was already assigned before
String animal = dao.joinGameInstance(jsonObj.get("idToken").getAsString(), jsonObj.get("gameInstanceId").getAsString());

// Convert the anima alias to JSON
String json = convertToJson(animal);
// Send the JSON as response
response.setContentType("application/json;");
response.getWriter().println(json);
}

/**
* Convert to JSON using Gson
*/
private String convertToJson(String newGameInstanceId) {
Gson gson = new Gson();
String json = gson.toJson(newGameInstanceId);
return json;
}

}
16 changes: 1 addition & 15 deletions src/main/webapp/student/scripts/enter-game.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,7 @@ function verifyGameInstanceExists(gameInstanceId) {

// Send the request to join the Game Instance
function joinGameInstance(gameInstanceId) {
firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
fetch('/joinGameInstance', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({idToken: idToken, gameInstanceId: gameInstanceId})
}).then(() => {
window.location.href = "/student/play-game.html?gameInstanceId=" + gameInstanceId;
});
}).catch(function(error) {
// Handle error
console.log("Please log in");
});
window.location.href = "/student/play-game.html?gameInstanceId=" + gameInstanceId;
}

// Display a message saying that GameInstanceId is not valid
Expand Down
40 changes: 31 additions & 9 deletions src/main/webapp/student/scripts/play-game.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ let active = false;
let currentQuestionId = null;
let selectedAnswerId = "";
let currentQuestionActive = false;
let gameInstanceId = getGameInstanceIdFromQueryParams();
let gameInstanceId = null;
const resultObject = document.getElementById("result");
let submited = false;
let isFinished = false;
Expand Down Expand Up @@ -49,25 +49,47 @@ function authStateObserver(user) {
async function loadGamePanel(user) {
// Get the Game Instance's ID in which the user is participating

gameInstanceId = getGameInstanceIdFromQueryParams();

if (gameInstanceId == null) {
gameInstanceId = await getActiveGameInstanceId(user);
}

// Register and get animal alias from Firestore, or if exists just retrieve animal alias
registerStudentInGameInstance(gameInstanceId);

// Start listening to the GameInstance
initGameInstanceListener(gameInstanceId);

// Get and display the user's id and alias
initStudentAlias(user, gameInstanceId);
}

// // Get and display the user's id and alias in the UI
function initStudentAlias(user, gameInstanceId) {
db.collection("gameInstance").doc(gameInstanceId).collection("students").doc(user.uid).get().then(function(doc) {
const userIdDivElement = document.getElementById('userId');
userIdDivElement.innerText = `You are: ${doc.data().alias}`
// Register and get animal alias from Firestore, or if exists just retrieve assigned animal alias
function registerStudentInGameInstance(gameInstanceId) {
firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
fetch('/joinGameInstance', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({idToken: idToken, gameInstanceId: gameInstanceId})
}).then((response) => {
response.json().then(animal => {
// Display the user's alias
initStudentAlias(animal);
});
});
}).catch(function(error) {
// Handle error
console.log("Please log in");
});
}

// Display the user's alias in the UI
function initStudentAlias(animalAlias) {
const userIdDivElement = document.getElementById('userId');
userIdDivElement.innerText = `You are: ${animalAlias}`
}

// Gets the gameInstanceId from the query string if there is
// If not, it returns null
function getGameInstanceIdFromQueryParams() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,18 @@
#cardActions {
text-align: center;
}

#jsShareGameInstance {
color: red;
cursor: pointer;
}

#jsShareGameInstance:hover {
color: blue;
cursor: pointer;
}

#jsShareGameInstance:active {
color: gray;
cursor: pointer;
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ <h1 class="mdl-card__title-text"><b>Game Info</b></h1>
<div class="mdl-card__supporting-text">
<div id="gameInfo">
<div id="jsGameInstanceId"></div>
<div id="jsShareGameInstance"></div>
<div id="jsNumberOfStudents"></div>
<div id="jsGameDetails">
<div id="jsGameId"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ function buildActiveGameInstanceUI({ gameInstanceId, gameInstance, game} = {}) {
function addGameInstanceIdToUI(gameInstanceId) {
const gameInstanceIdElement = document.getElementById("jsGameInstanceId");
gameInstanceIdElement.innerText = "This gameInstance's ID is: " + gameInstanceId;

const shareGameInstanceElement = document.getElementById('jsShareGameInstance');
shareGameInstanceElement.innerText = "Share this link with your students for them to join (click to copy to clipboard): " + "https://quizzy-step-2020.uc.r.appspot.com/student/play-game.html?gameInstanceId=" + gameInstanceId;
shareGameInstanceElement.addEventListener('click', () => {
navigator.clipboard.writeText("https://quizzy-step-2020.uc.r.appspot.com/student/play-game.html?gameInstanceId=" + gameInstanceId);
});
}

// Adds the Game's details to the UI
Expand Down Expand Up @@ -479,9 +485,7 @@ function addQuestionAnswerToHistoryUI({ questionId, answerId, answer } = {}) {
answerInQuestionStatsDivElement.innerText = answer.title + ' with ' + answer.numberAnswers + ' answers.';

if (answer.correct) {
questionAnswerDivElement.innerText = 'Correctly answered, chose: "' + answer.chosen + '"';
} else {
questionAnswerDivElement.innerText = 'Incorrect answer, chose: "' + answer.chosen + '"';
answerInQuestionStatsDivElement.innerText += ' (Correct answer)';
}

// Add the answer to its component in the DOM
Expand Down

0 comments on commit d8b8659

Please sign in to comment.