diff --git a/app/src/main/java/com/yearthreeproject/xbframework/GroupsActivity.java b/app/src/main/java/com/yearthreeproject/xbframework/GroupsActivity.java index c22c28f9176ca534aec5fb6db4f0a59e1f4ce0a0..909fc4c6d4ca420293ed9ed8dff3c5973552ebdb 100644 --- a/app/src/main/java/com/yearthreeproject/xbframework/GroupsActivity.java +++ b/app/src/main/java/com/yearthreeproject/xbframework/GroupsActivity.java @@ -1,19 +1,49 @@ package com.yearthreeproject.xbframework; +import android.app.AlertDialog; +import android.content.Intent; import android.os.Build; import android.os.Bundle; +import android.text.InputFilter; +import android.text.InputType; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import org.bson.Document; + import java.util.Objects; +import java.util.concurrent.ExecutionException; + +import io.realm.mongodb.App; +import io.realm.mongodb.mongo.MongoCollection; +import io.realm.mongodb.mongo.iterable.MongoCursor; + +import static com.google.android.gms.tasks.Tasks.await; public class GroupsActivity extends AppCompatActivity { + private static final String TAG = "GroupsActivity"; + + private App realmApp; + + private Menu infoMenu; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { + realmApp = ((MongoRealmApp)this.getApplication()).getApp(); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_groups); + Toolbar toolbar = findViewById(R.id.toolbar); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { toolbar.setNestedScrollingEnabled(false); @@ -24,7 +54,78 @@ public class GroupsActivity extends AppCompatActivity { getSupportActionBar().setDisplayUseLogoEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true); + LinearLayout groupLayout = findViewById(R.id.GroupActivityLayout); + new Thread(()->{ + try { + MongoCollection<Document> groupCollection = realmApp.currentUser().getMongoClient("mongodb-atlas").getDatabase("V1").getCollection("Groups"); + MongoCursor<Document> found = await(groupCollection.find(new Document("users", new Document("$elemMatch", new Document("$eq", realmApp.currentUser().getId())))).iterator()); + Log.d(TAG, "onCreate: " + found); + while (found.hasNext()) { + Document group = found.next(); + Button groupButton = new Button(this); + groupButton.setText(group.getString("name")); + groupButton.setOnClickListener(v ->{ + Log.d(TAG, "onCreate: " + group.toString()); + Intent groupExperiment = new Intent(this, SurveyResponseActivity.class); + groupExperiment.putExtra("group", group.toJson()); + startActivity(groupExperiment); + }); + groupLayout.post(() -> groupLayout.addView(groupButton)); + } + } catch(InterruptedException | ExecutionException e){ + e.printStackTrace(); + } + }).start(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.groups_menu, menu); + infoMenu = menu; + return true; + } + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int id = item.getItemId(); + if (id == R.id.add_group) + { + final String[] m_Text = {""}; + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Enter the group id:"); + final EditText input = new EditText(this); + input.setInputType(InputType.TYPE_CLASS_TEXT); + input.setFilters(new InputFilter[] {new InputFilter.LengthFilter(6)}); + builder.setView(input); + builder.setPositiveButton("OK", (dialog, which) -> { + new Thread(() -> { + try { + m_Text[0] = input.getText().toString(); + Log.d(TAG, "onOptionsItemSelected: " + m_Text[0]); + // attach the user to the group - if it exists, otherwise tell the user that the group does not exist: + MongoCollection<Document> groupCollection = realmApp.currentUser().getMongoClient("mongodb-atlas").getDatabase("V1").getCollection("Groups"); + MongoCollection<Document> userCollection = realmApp.currentUser().getMongoClient("mongodb-atlas").getDatabase("V1").getCollection("Users"); + + // check if the code does not match one that the user is already in then apply the filter + + Document foundDocument = await(groupCollection.findOneAndUpdate(new Document("identifier", m_Text[0]), new Document("$addToSet", new Document("users", realmApp.currentUser().getId())))); + if(foundDocument != null) { + Log.d(TAG, "onOptionsItemSelected: found document " + foundDocument); + Document userUpdate = await(userCollection.findOneAndUpdate(new Document("_user_id", realmApp.currentUser().getId()), new Document("$addToSet", new Document("groups", foundDocument.getObjectId("_id"))))); + Log.d(TAG, "onOptionsItemSelected: updated user" + userUpdate); + } else { + // this means the group does not exist in the database + Log.d(TAG, "onOptionsItemSelected: no document found (do a popup for this result)"); + } + } catch (ExecutionException | InterruptedException e) { + e.printStackTrace(); + } + }).start(); + }); + builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel()); + builder.show(); + } + return super.onOptionsItemSelected(item); } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/yearthreeproject/xbframework/MainActivity.java b/app/src/main/java/com/yearthreeproject/xbframework/MainActivity.java index eb8e455123a5f3ae2fb444274fb2fba41dc829ac..58bd88c599d4ca367b8db9ae822eef47a9132c93 100644 --- a/app/src/main/java/com/yearthreeproject/xbframework/MainActivity.java +++ b/app/src/main/java/com/yearthreeproject/xbframework/MainActivity.java @@ -52,7 +52,7 @@ public class MainActivity extends AppCompatActivity { private MongoCollection<Document> userCollection; private MongoCollection<Document> experimentsCollection; - Menu infoMenu; + private Menu infoMenu; @RequiresApi(api = Build.VERSION_CODES.N) @Override @@ -134,11 +134,9 @@ public class MainActivity extends AppCompatActivity { ProjectMacros.saveFile(MainActivity.this, "localUserData.json", user.toString()); - - // DEBUG INTENT FOR QUICK ACCESS TO ANOTHER INTENT - Intent open_quicker_DEBUG = new Intent(this, MetronomeActivity.class); - startActivity(open_quicker_DEBUG); - + /*// DEBUG INTENT FOR QUICK ACCESS TO ANOTHER INTENT + Intent open_quicker_DEBUG = new Intent(this, MetronomeActivity.class); + startActivity(open_quicker_DEBUG);*/ if(user.optJSONObject("current_experiment").optBoolean("locked", false)) checkReleaseFromExperiment(); else checkNotifications(); @@ -156,6 +154,11 @@ public class MainActivity extends AppCompatActivity { homeLayout.removeView(surveyButton); } + Button metronome = new Button(this); + metronome.setText("Metronome"); + homeLayout.addView(metronome); + metronome.setOnClickListener(v -> startActivity(new Intent(this, MetronomeActivity.class))); + Button logoutButton = findViewById(R.id.HomeLogoutButton); logoutButton.setOnClickListener(v -> realmApp.currentUser().logOutAsync(logoutTask -> { SharedPreferences.Editor savedSettingsEditor = savedSettings.edit(); @@ -171,6 +174,9 @@ public class MainActivity extends AppCompatActivity { Button progressButton = findViewById(R.id.HomeProgressButton); progressButton.setOnClickListener(v -> launchProgressPage()); + Button groupsButton = findViewById(R.id.HomeGroupsButton); + groupsButton.setOnClickListener(v -> startActivity(new Intent(this, GroupsActivity.class))); + experimentsButton.setOnClickListener(v -> launchBoxPage()); surveyButton.setOnClickListener(this::surveyButtonEvent); diff --git a/app/src/main/java/com/yearthreeproject/xbframework/SurveyResponseActivity.java b/app/src/main/java/com/yearthreeproject/xbframework/SurveyResponseActivity.java index 640564569428ca4f33110ca1f1670364847ef671..b48e92a069540ddc18f1b9c03b8583dfc1b3eda3 100644 --- a/app/src/main/java/com/yearthreeproject/xbframework/SurveyResponseActivity.java +++ b/app/src/main/java/com/yearthreeproject/xbframework/SurveyResponseActivity.java @@ -9,7 +9,10 @@ import android.text.Html; import android.text.InputType; import android.text.TextWatcher; import android.util.DisplayMetrics; +import android.util.Log; import android.view.Gravity; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; @@ -19,6 +22,7 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AlertDialog; @@ -28,7 +32,6 @@ import androidx.appcompat.widget.Toolbar; import com.google.android.material.floatingactionbutton.FloatingActionButton; import org.bson.Document; -import org.bson.types.ObjectId; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -59,6 +62,9 @@ public class SurveyResponseActivity extends AppCompatActivity { private final List<JSONObject> surveyResponses = new ArrayList<>(); private final List<JSONObject> perceptionResponses = new ArrayList<>(); + private JSONObject experimentJSON; + private Document groupDocument = null; + @Override public boolean onSupportNavigateUp() { finish(); @@ -74,24 +80,52 @@ public class SurveyResponseActivity extends AppCompatActivity { .show(); } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + if(getIntent().getStringExtra("group") != null) { + getMenuInflater().inflate(R.menu.survey_menu, menu); + return true; + } else { + return false; + } + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int id = item.getItemId(); + if (id == R.id.menu_group_info) + { + Log.d(TAG, "onOptionsItemSelected: info pressed"); + } + return super.onOptionsItemSelected(item); + } + @SuppressLint("NewApi") @RequiresApi(api = Build.VERSION_CODES.KITKAT) @Override protected void onCreate(@Nullable Bundle savedInstanceState) { realmApp = ((MongoRealmApp)this.getApplication()).getApp(); + super.onCreate(savedInstanceState); setContentView(R.layout.activity_survey_response); Toolbar toolbar = findViewById(R.id.toolbar); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - toolbar.setNestedScrollingEnabled(false); - } + toolbar.setNestedScrollingEnabled(false); setSupportActionBar(toolbar); Objects.requireNonNull(getSupportActionBar()).setDisplayShowHomeEnabled(true); getSupportActionBar().setDisplayUseLogoEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true); + boolean group = getIntent().getStringExtra("group") != null; + if(group){ + groupDocument = Document.parse(getIntent().getStringExtra("group")); + setTitle(groupDocument.getString("name")); + } + + Log.d(TAG, "onCreate: groupDocument " + groupDocument); + + MongoCollection<Document> experimentCollection = realmApp.currentUser().getMongoClient("mongodb-atlas").getDatabase("V1").getCollection("Experiments"); LinearLayout surveyScrollView = findViewById(R.id.SurveyScrollView); @@ -101,82 +135,114 @@ public class SurveyResponseActivity extends AppCompatActivity { surveyScrollView.addView(newHR(this, 8, "#888888")); - try { - TextView perceptionTitle = new TextView(this); - perceptionTitle.setText("Perception Survey"); - perceptionTitle.setTextSize(Float.parseFloat("26")); + Document finalGroupDocument = groupDocument; + new Thread(()->{ + try { + Document experimentDocument = null; + + if(group){ + d(TAG, "onCreate: finalGroupDocumentExperiment " + finalGroupDocument.get("current_experiment")); + experimentDocument = await(experimentCollection.findOne(new Document("_id", finalGroupDocument.get("current_experiment", Document.class).getObjectId("id")))); + experimentJSON = new JSONObject(experimentDocument.toJson()); + } else { + JSONObject localUserJSON = new JSONObject(ProjectMacros.readFile(this, "localUserData.json")); + experimentJSON = localUserJSON.getJSONObject("current_experiment").getJSONArray("experiment").getJSONObject(0); + } - surveyScrollView.addView(perceptionTitle); + d(TAG, "onCreate: experimentDocument " + experimentDocument); - perceptionResponses.add(new JSONObject() - .put("type", "compare") - .put("response", JSONObject.NULL) - .put("question", "How do you feel compared to yesterday?")); - surveyScrollView.addView(createNewQuestions("How do you feel compared to yesterday?", "compare", 0, perceptionResponses)); + TextView perceptionTitle = new TextView(this); + perceptionTitle.setText("Perception Survey"); + perceptionTitle.setTextSize(Float.parseFloat("26")); + surveyScrollView.post(()->surveyScrollView.addView(perceptionTitle)); - JSONObject localUserJson = new JSONObject(ProjectMacros.readFile(this, "localUserData.json")); + perceptionResponses.add(new JSONObject() + .put("type", "compare") + .put("response", JSONObject.NULL) + .put("question", "How do you feel compared to yesterday?")); + surveyScrollView.post(()-> surveyScrollView.addView(createNewQuestions("How do you feel compared to yesterday?", "compare", 0, perceptionResponses))); - if("Sleep".equals(localUserJson.getJSONObject("current_experiment").getJSONArray("experiment").getJSONObject(0).optString("category"))){ - getSupportActionBar().setLogo(R.mipmap.sleep_logo); - } else if ("Eat".equals(localUserJson.getJSONObject("current_experiment").getJSONArray("experiment").getJSONObject(0).optString("category"))){ - getSupportActionBar().setLogo(R.mipmap.eat_logo); - } else if("Engage".equals(localUserJson.getJSONObject("current_experiment").getJSONArray("experiment").getJSONObject(0).optString("category"))){ - getSupportActionBar().setLogo(R.mipmap.engage_logo); - } else { - // this is always going to be default since there is no check to see what the result actuall is... - getSupportActionBar().setLogo(R.mipmap.ic_launcher); - } + d(TAG, "onCreate: experimentJSON " + experimentJSON); - JSONArray completionQuestions = localUserJson.getJSONObject("current_experiment").getJSONArray("experiment").getJSONObject(0).optJSONArray("completion_questions"); + if("Sleep".equals(experimentJSON.optString("category"))){ + getSupportActionBar().setLogo(R.mipmap.sleep_logo); + } else if ("Eat".equals(experimentJSON.optString("category"))){ + getSupportActionBar().setLogo(R.mipmap.eat_logo); + } else if("Engage".equals(experimentJSON.optString("category"))){ + getSupportActionBar().setLogo(R.mipmap.engage_logo); + } else { + // this is always going to be default since there is no check to see what the result actually is... + toolbar.post(()-> getSupportActionBar().setLogo(R.mipmap.ic_launcher)); + } + JSONArray completionQuestions = experimentJSON.optJSONArray("completion_questions"); + d(TAG, "onCreate: completionQuestions " + completionQuestions); - if(completionQuestions != null){ - TextView completionTitle = new TextView(this); - completionTitle.setText("Completion Survey"); - completionTitle.setTextSize(Float.parseFloat("26")); - surveyScrollView.addView(completionTitle); + if(completionQuestions != null){ + TextView completionTitle = new TextView(this); + completionTitle.setText("Completion Survey"); + completionTitle.setTextSize(Float.parseFloat("26")); - for (int i = 0; i < completionQuestions.length(); i++) { - completionResponses.add(new JSONObject() - .put("type", completionQuestions.getJSONObject(i).getString("type")) - .put("response", JSONObject.NULL) - .put("question", completionQuestions.getJSONObject(i).getString("question")) - .put("expected", completionQuestions.getJSONObject(i).getString("expected"))); + surveyScrollView.post(()-> surveyScrollView.addView(completionTitle)); - surveyScrollView.addView(createNewQuestions(completionQuestions.getJSONObject(i).optString("question"), completionQuestions.getJSONObject(i).optString("type"), i, completionResponses)); - } + for (int i = 0; i < completionQuestions.length(); i++) { + completionResponses.add(new JSONObject() + .put("type", completionQuestions.getJSONObject(i).getString("type")) + .put("response", JSONObject.NULL) + .put("question", completionQuestions.getJSONObject(i).getString("question")) + .put("expected", completionQuestions.getJSONObject(i).getString("expected"))); - surveyScrollView.addView(newHR(this, 8, "#888888")); - } + int finalI = i; + surveyScrollView.post(()-> { + try { + surveyScrollView.addView(createNewQuestions(completionQuestions.getJSONObject(finalI).optString("question"), completionQuestions.getJSONObject(finalI).optString("type"), finalI, completionResponses)); + } catch (JSONException e) { + e.printStackTrace(); + } + }); + } + + surveyScrollView.post(()-> surveyScrollView.addView(newHR(this, 8, "#888888"))); + } - JSONArray surveyQuestions = localUserJson.getJSONObject("current_experiment").getJSONArray("experiment").getJSONObject(0).optJSONArray("survey_questions"); + JSONArray surveyQuestions = experimentJSON.optJSONArray("survey_questions"); + d(TAG, "onCreate: surveyQuestions " + surveyQuestions); - if(surveyQuestions != null){ - TextView surveyTagTitle = new TextView(this); - surveyTagTitle.setText("Scientific Survey"); - surveyTagTitle.setTextSize(Float.parseFloat("26")); + if(surveyQuestions != null){ + TextView surveyTagTitle = new TextView(this); + surveyTagTitle.setText("Scientific Survey"); + surveyTagTitle.setTextSize(Float.parseFloat("26")); - surveyScrollView.addView(surveyTagTitle); - for (int i = 0; i < surveyQuestions.length(); i++) { - surveyResponses.add(new JSONObject() - .put("type", surveyQuestions.getJSONObject(i).getString("type")) - .put("agree", surveyQuestions.getJSONObject(i).optString("agree", "good")) - .put("response", JSONObject.NULL) - .put("question", surveyQuestions.getJSONObject(i).getString("question"))); + surveyScrollView.post(()-> surveyScrollView.addView(surveyTagTitle)); + for (int i = 0; i < surveyQuestions.length(); i++) { + surveyResponses.add(new JSONObject() + .put("type", surveyQuestions.getJSONObject(i).getString("type")) + .put("agree", surveyQuestions.getJSONObject(i).optString("agree", "good")) + .put("response", JSONObject.NULL) + .put("question", surveyQuestions.getJSONObject(i).getString("question"))); - surveyScrollView.addView(createNewQuestions(surveyQuestions.getJSONObject(i).optString("question"), surveyQuestions.getJSONObject(i).optString("type"), i, surveyResponses)); + int finalI = i; + surveyScrollView.post(()-> { + try { + surveyScrollView.addView(createNewQuestions(surveyQuestions.getJSONObject(finalI).optString("question"), surveyQuestions.getJSONObject(finalI).optString("type"), finalI, surveyResponses)); + } catch (JSONException e) { + e.printStackTrace(); + } + }); + } } + } catch (JSONException | ExecutionException | InterruptedException e) { + e.printStackTrace(); } - } catch (JSONException e) { - e.printStackTrace(); - } + }).start(); FloatingActionButton fab = findViewById(R.id.surveyExperimentFAB); fab.setOnClickListener(v -> completeSubmission()); } + @RequiresApi(api = Build.VERSION_CODES.KITKAT) private void completeSubmission() { boolean correctSubmission = true; ArrayList<Document> rawCompletionResults = new ArrayList<>(); @@ -202,11 +268,11 @@ public class SurveyResponseActivity extends AppCompatActivity { int upperValue = Integer.parseInt(values[1]); if (queryInt <= upperValue && lowerValue <= queryInt) { - d("test", "int completed correctly"); + d(TAG, "int completed correctly"); completedResults++; } } else if(queryInt == lowerValue) { - d("test", "int completed correctly"); + d(TAG, "int completed correctly"); completedResults++; } } @@ -226,17 +292,17 @@ public class SurveyResponseActivity extends AppCompatActivity { Integer.parseInt(queryTime[1]) <= Integer.parseInt(upperTime[1])){ // If upper hour is the same // && if the minutes are below the threshold for upper time, if yes, correct - d("test", "date completed correctly"); + d(TAG, "date completed correctly"); completedResults++; } else if (Integer.parseInt(lowerTime[0]) == Integer.parseInt(queryTime[0]) && Integer.parseInt(lowerTime[1]) <= Integer.parseInt(queryTime[1])){ // If lower hour is the same // && if the minutes are above the threshold for lowest time, if yes, correct - d("test", "date completed correctly"); + d(TAG, "date completed correctly"); completedResults++; } else { // If neither are the same, and it fits within the range, minutes are irrelevant - d("test", "date completed correctly"); + d(TAG, "date completed correctly"); completedResults++; } } @@ -246,7 +312,7 @@ public class SurveyResponseActivity extends AppCompatActivity { if(!completionResponses.get(i).optString("expected").equals("null")){ totalPossibleResults++; if(completionResponses.get(i).optString("response").equals(completionResponses.get(i).optString("expected"))) { - d("test", "default completed correctly"); + d(TAG, "default completed correctly"); completedResults++; } } @@ -254,9 +320,9 @@ public class SurveyResponseActivity extends AppCompatActivity { } - d("test", completedResults + "/" + totalPossibleResults); + d(TAG, "completionPercent calculation "+completedResults + "/" + totalPossibleResults); double completionPercent = (completedResults / (double) totalPossibleResults)*100; - d("test", String.valueOf(completionPercent)); + d(TAG, "completionPercent " + completionPercent); int perceptionResponseTotal = 0; for (int i = 0; i < surveyResponses.size(); i++) { @@ -270,7 +336,7 @@ public class SurveyResponseActivity extends AppCompatActivity { } double responseAverage = (perceptionResponseTotal / (double) (surveyResponses.size()+1))*100; - d(TAG, "completeSubmission: " + responseAverage); + d(TAG, "completeSubmission: responseAverage " + responseAverage); for(int i = 0; i < perceptionResponses.size(); i++){ if(perceptionResponses.get(i).optString("response").equals("null")) correctSubmission = false; @@ -284,89 +350,108 @@ public class SurveyResponseActivity extends AppCompatActivity { .setPositiveButton("Yes", (dialog, which) -> { new Thread(() -> { try { + JSONObject localUserJson = new JSONObject(ProjectMacros.readFile(this, "localUserData.json")); MongoCollection<Document> responseCollection = realmApp.currentUser().getMongoClient("mongodb-atlas").getDatabase("V1").getCollection("Responses"); MongoCollection<Document> completionCollection = realmApp.currentUser().getMongoClient("mongodb-atlas").getDatabase("V1").getCollection("Completions"); MongoCollection<Document> perceptionCollection = realmApp.currentUser().getMongoClient("mongodb-atlas").getDatabase("V1").getCollection("Perceptions"); MongoCollection<Document> userCollection = realmApp.currentUser().getMongoClient("mongodb-atlas").getDatabase("V1").getCollection("Users"); - JSONObject userJSON = new JSONObject(ProjectMacros.readFile(this, "localUserData.json")); - Document currentExperiment = Document.parse(userJSON.getJSONObject("current_experiment").toString()); + Document currentExperiment = Document.parse(experimentJSON.toString()); Date end_date = new Date(); - end_date.setTime(Long.parseLong(userJSON.getJSONObject("current_experiment").getJSONObject("date_until").getString("$date"))); + end_date.setTime(groupDocument.get("current_experiment", Document.class).getDate("date_until").getTime()); Document responsesDocument = null; Document completionsDocument = null; Document perceptionsDocument = null; if(rawSurveyResults.size() > 0){ + Document queryDocument = new Document("_user_id", realmApp.currentUser().getId()); + queryDocument.append("date", today); + if(groupDocument != null){ + queryDocument.append("group", groupDocument.getObjectId("_id")); + } else { + queryDocument.append("group", new Document("$eq", null)); + } + Document responseDocument = new Document("_user_id", realmApp.currentUser().getId()) .append("date", today) .append("end_date", end_date) .append("experiment", currentExperiment.getObjectId("id")) - .append("responses", rawSurveyResults); + .append("responses", rawSurveyResults) + .append("group", groupDocument.getObjectId("_id")); - responsesDocument = await(responseCollection.findOneAndUpdate(new Document("_user_id", realmApp.currentUser().getId()).append("date", today), + responsesDocument = await(responseCollection.findOneAndUpdate(queryDocument, responseDocument, new FindOneAndModifyOptions().upsert(true))); - d(TAG, "completeSubmission: " + responsesDocument); + d(TAG, "completeSubmission: responsesDocument " + responsesDocument); } if(rawCompletionResults.size() > 0){ + Document queryDocument = new Document("_user_id", realmApp.currentUser().getId()); + queryDocument.append("date", today); + if(groupDocument != null){ + queryDocument.append("group", groupDocument.getObjectId("_id")); + } else { + queryDocument.append("group", new Document("$eq", null)); + } + Document completionDocument = new Document("_user_id", realmApp.currentUser().getId()) .append("date", today) .append("end_date", end_date) .append("experiment", currentExperiment.getObjectId("id")) .append("responses", rawCompletionResults) - .append("completion_percent", (int) completionPercent); + .append("completion_percent", (int) completionPercent) + .append("group", groupDocument.getObjectId("_id")); - completionsDocument = await(completionCollection.findOneAndUpdate(new Document("_user_id", realmApp.currentUser().getId()).append("date", today), + completionsDocument = await(completionCollection.findOneAndUpdate(queryDocument, completionDocument, new FindOneAndModifyOptions().upsert(true))); - d(TAG, "completeSubmission: " + completionsDocument); + d(TAG, "completeSubmission: completionsDocument " + completionsDocument); } - d(TAG, "completeSubmission: " + rawPerceptionResults.size()); + d(TAG, "completeSubmission: rawPerceptionResultsSize " + rawPerceptionResults.size()); if(rawPerceptionResults.size() > 0){ + Document queryDocument = new Document("_user_id", realmApp.currentUser().getId()); + queryDocument.append("date", today); + if(groupDocument != null){ + queryDocument.append("group", groupDocument.getObjectId("_id")); + } else { + queryDocument.append("group", new Document("$eq", null)); + } + Document perceptionDocument = new Document("_user_id", realmApp.currentUser().getId()) .append("date", today) .append("end_date", end_date) .append("experiment", currentExperiment.getObjectId("id")) - .append("responses", rawPerceptionResults); + .append("responses", rawPerceptionResults) + .append("group", groupDocument.getObjectId("_id")); - perceptionsDocument = await(perceptionCollection.findOneAndUpdate(new Document("_user_id", realmApp.currentUser().getId()).append("date", today), + perceptionsDocument = await(perceptionCollection.findOneAndUpdate(queryDocument, perceptionDocument, new FindOneAndModifyOptions().upsert(true))); - d(TAG, "completeSubmission: " + perceptionsDocument); + d(TAG, "completeSubmission: perceptionsDocument " + perceptionsDocument); } - Document userDocument = await(userCollection.findOne(new Document("_user_id", realmApp.currentUser().getId()))); - - ObjectId completionId = null; - ObjectId responseId = null; - ObjectId perceptionId = null; - - if(completionId != null) completionId = completionsDocument.getObjectId("_id"); - if(responseId != null) responseId = completionsDocument.getObjectId("_id"); - if(perceptionId != null) perceptionId = completionsDocument.getObjectId("_id"); - - if (completionsDocument != null && !userDocument.getList("experiment_completions", ObjectId.class).contains(completionId)) - userDocument.put("experiment_completions", userDocument.getList("experiment_completions", ObjectId.class).add(completionId)); - - if (responsesDocument != null && !userDocument.getList("results", ObjectId.class).contains(responseId)) - userDocument.put("results", userDocument.getList("results", ObjectId.class).add(responseId)); - - if(perceptionsDocument != null && !userDocument.getList("perceptions", ObjectId.class).contains(perceptionId)) - userDocument.put("perceptions", userDocument.getList("perceptions", ObjectId.class).add(perceptionId)); - - userCollection.updateOne(new Document("_user_id", realmApp.currentUser().getId()), - userDocument).addOnCompleteListener(user_update_task -> { - if (user_update_task.isSuccessful()) { - finish(); - } else { - d("dbg", String.valueOf(user_update_task.getException())); - } - }); + Document userDocument = new Document(); + Document queryDocument = new Document("_user_id", realmApp.currentUser().getId()); + if (groupDocument != null) queryDocument.put("group", groupDocument.getObjectId("_id")); + if (completionsDocument != null) { + userDocument.put("$addToSet", new Document("experiment_completions", completionsDocument.getObjectId("_id"))); + d(TAG, "completeSubmission: userDocument " + userDocument); + await(userCollection.updateOne(queryDocument, userDocument)); + } + if (responsesDocument != null) { + userDocument.put("$addToSet", new Document("results", responsesDocument.getObjectId("_id"))); + d(TAG, "completeSubmission: userDocument " + userDocument); + await(userCollection.updateOne(queryDocument, userDocument)); + } + if (perceptionsDocument != null) { + userDocument.put("$addToSet", new Document("perceptions", perceptionsDocument.getObjectId("_id"))); + d(TAG, "completeSubmission: userDocument " + userDocument); + await(userCollection.updateOne(queryDocument, userDocument)); + } + finish(); } catch (JSONException| InterruptedException | ExecutionException e) { e.printStackTrace(); } @@ -484,7 +569,7 @@ public class SurveyResponseActivity extends AppCompatActivity { buttonArray.get(x).setChecked(true); JSONObject result = responseGroup.get(index) .put("response", responseString); - d("dbg", String.valueOf(result)); + d(TAG, String.valueOf(result)); responseGroup.set(index, result); } catch (JSONException e){ e.printStackTrace(); @@ -541,7 +626,7 @@ public class SurveyResponseActivity extends AppCompatActivity { buttonArray.get(x).setChecked(true); JSONObject result = responseGroup.get(index) .put("response", x == 0 ? "Yes" : "No"); - d("dbg", String.valueOf(result)); + d(TAG, String.valueOf(result)); responseGroup.set(index, result); } catch (JSONException e){ e.printStackTrace(); @@ -568,7 +653,7 @@ public class SurveyResponseActivity extends AppCompatActivity { try { JSONObject result = responseGroup.get(index) .put("response", notificationTextViewTemp); - d("dbg", String.valueOf(result)); + d(TAG, String.valueOf(result)); responseGroup.set(index, result); } catch (JSONException e){ e.printStackTrace(); @@ -601,7 +686,7 @@ public class SurveyResponseActivity extends AppCompatActivity { try { JSONObject result = responseGroup.get(index) .put("response", s.toString()); - d("dbg", String.valueOf(result)); + d(TAG, String.valueOf(result)); responseGroup.set(index, result); } catch (JSONException e){ e.printStackTrace(); @@ -630,7 +715,7 @@ public class SurveyResponseActivity extends AppCompatActivity { try { JSONObject result = responseGroup.get(index) .put("response", s.toString()); - d("dbg", String.valueOf(result)); + d(TAG, String.valueOf(result)); responseGroup.set(index, result); } catch (JSONException e){ e.printStackTrace(); @@ -728,7 +813,7 @@ public class SurveyResponseActivity extends AppCompatActivity { buttonArray.get(x).setChecked(true); JSONObject result = responseGroup.get(index) .put("response", response); - d("dbg", String.valueOf(result)); + d(TAG, String.valueOf(result)); responseGroup.set(index, result); } catch (JSONException e){ e.printStackTrace(); diff --git a/app/src/main/res/layout/activity_groups.xml b/app/src/main/res/layout/activity_groups.xml new file mode 100644 index 0000000000000000000000000000000000000000..e4abba78bb1b2f3288fe7e833c2199ba5da28453 --- /dev/null +++ b/app/src/main/res/layout/activity_groups.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".GroupsActivity"> + + <com.google.android.material.appbar.AppBarLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/colorPrimary" + android:minHeight="56dp" + android:theme="@style/ThemeOverlay.AppCompat.ActionBar" + app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> + + </com.google.android.material.appbar.AppBarLayout> + + + <include layout="@layout/content_groups" /> + + +</androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/app/src/main/res/layout/content_groups.xml b/app/src/main/res/layout/content_groups.xml new file mode 100644 index 0000000000000000000000000000000000000000..8699cbe2752e0370cb5b3215b54a6f2ddf71dd4e --- /dev/null +++ b/app/src/main/res/layout/content_groups.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/GroupActivityLayout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_margin="16dp" + android:layout_marginTop="32dp" + android:orientation="vertical" + app:layout_behavior="@string/appbar_scrolling_view_behavior" + tools:context=".GroupsActivity" + tools:showIn="@layout/activity_groups"> + +</LinearLayout> diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml index 66db628868dba26f5da5a2b9c01bbd9d301cbd12..3abeef5e21fa88a983288309da336a868f7ac1d9 100644 --- a/app/src/main/res/layout/content_main.xml +++ b/app/src/main/res/layout/content_main.xml @@ -39,6 +39,15 @@ android:layout_weight="1" android:text="@string/MainProgress" /> + <Button + android:id="@+id/HomeGroupsButton" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:backgroundTint="@color/colorPrimaryAccent" + android:text="@string/MainGroups" + android:textColor="@color/colorPrimary" /> + <Button android:id="@+id/HomeAboutButton" android:layout_width="match_parent" diff --git a/app/src/main/res/menu/groups_menu.xml b/app/src/main/res/menu/groups_menu.xml new file mode 100644 index 0000000000000000000000000000000000000000..6ef3c78e5ffd7b9da5d8e022dad9315943c29f7d --- /dev/null +++ b/app/src/main/res/menu/groups_menu.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:android="http://schemas.android.com/apk/res/android"> + + <item + android:id="@+id/add_group" + android:icon="@android:drawable/ic_menu_add" + android:title="Add group" + app:showAsAction="ifRoom" /> +</menu> \ No newline at end of file diff --git a/app/src/main/res/menu/survey_menu.xml b/app/src/main/res/menu/survey_menu.xml new file mode 100644 index 0000000000000000000000000000000000000000..19b55c4e89b26d781969dcbfe8a64ad2d4e8ef65 --- /dev/null +++ b/app/src/main/res/menu/survey_menu.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:android="http://schemas.android.com/apk/res/android"> + + <item + android:id="@+id/menu_group_info" + android:icon="@drawable/ic_baseline_info_24" + android:title="GroupSurveyInfo" + app:showAsAction="ifRoom" /> +</menu> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c8f16b5ee678ba6509924ef74d8c37e697b5cea..2546347c048e4e96c500ea800e00bd4f482ed8d4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -180,5 +180,6 @@ <string name="startButtonLabel">Start</string> <string name="stopButtonLabel">Stop</string> <string name="two">Two</string> + <string name="MainGroups">Groups</string> <!-- Metronome strings End --> </resources>