Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Noora new features #1347

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/src/main/java/org/digitalcampus/mobile/quiz/Quiz.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public class Quiz implements Serializable {
public static final String JSON_PROPERTY_TEXT = "text";
public static final String JSON_PROPERTY_TOLERANCE = "tolerance";
public static final String JSON_PROPERTY_FEEDBACK = "feedback";
public static final String JSON_PROPERTY_FEEDBACK_HTML_FILE = "feedbackhtmlfile";
public static final String JSON_PROPERTY_CORRECTFEEDBACK = "correctfeedback";
public static final String JSON_PROPERTY_INCORRECTFEEDBACK = "incorrectfeedback";
public static final String JSON_PROPERTY_PARTIALLYCORRECTFEEDBACK = "partiallycorrectfeedback";
Expand Down Expand Up @@ -292,6 +293,7 @@ private Response setResponseOptions(JSONObject r) throws JSONException{
}
responseOption.setProps(rProps);
responseOption.setFeedback(this.defaultLang);
responseOption.setFeedbackHtml(this.defaultLang);
return responseOption;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import org.digitalcampus.mobile.quiz.Quiz;
import org.digitalcampus.oppia.analytics.Analytics;
import org.digitalcampus.oppia.utils.TextUtilsJava;
import org.json.JSONException;
import org.json.JSONObject;

Expand All @@ -31,7 +30,7 @@
import java.util.List;
import java.util.Map;

public class QuizQuestion implements Serializable {
public abstract class QuizQuestion implements Serializable {

public static final String TAG = QuizQuestion.class.getSimpleName();
private static final long serialVersionUID = 852385823168202643L;
Expand All @@ -49,6 +48,7 @@ public class QuizQuestion implements Serializable {
protected List<Response> responseOptions = new ArrayList<>();
protected List<String> userResponses = new ArrayList<>();
protected String feedback = "";
protected String feedbackHtmlFile = "";
private boolean skipped;

public void addResponseOption(Response r) {
Expand All @@ -74,25 +74,9 @@ public void clearUserResponses() {
this.userResponses.clear();
}

public void mark(String lang) {
// loop through the responses
// find whichever are set as selected and add up the responses
float total = 0;
for (Response r : responseOptions) {
for (String a : userResponses) {
if (r.getTitle(lang).equals(a)) {
total += r.getScore();
String feedbackLang = r.getFeedback(lang);
if (!TextUtilsJava.isEmpty(feedbackLang)) {
feedback = feedbackLang;
}
}
}
}
this.calculateUserscore(total);
}
public abstract void mark(String lang);

public void calculateUserscore(float total){
protected void calculateUserscore(float total){
if (this.getProp(Quiz.JSON_PROPERTY_MAXSCORE) != null) {
int maxscore = Integer.parseInt(this.getProp(Quiz.JSON_PROPERTY_MAXSCORE));
if (total > maxscore) {
Expand Down Expand Up @@ -150,6 +134,13 @@ public String getFeedback(String lang) {
return this.feedback;
}

public String getFeedbackHtmlFile(String lang) {
// reset feedback back to nothing
this.feedbackHtmlFile = "";
this.mark(lang);
return this.feedbackHtmlFile;
}

public int getMaxScore() {
return Integer.parseInt(this.getProp(Quiz.JSON_PROPERTY_MAXSCORE));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class Response implements Serializable {
private float score;
private Map<String, String> props = new HashMap<>();
private Map<String, String> feedback = new HashMap<>();
private Map<String, String> feedbackHtml = new HashMap<>();

public String getTitle(String lang) {
if (title.containsKey(lang)) {
Expand Down Expand Up @@ -93,9 +94,37 @@ public String getFeedback(String lang) {
}
}

public Float getTolerance(){
public void setFeedbackHtml(String defaultLang) {
if (this.props.containsKey(Quiz.JSON_PROPERTY_FEEDBACK_HTML_FILE)) try {
JSONObject feedbackLangs = new JSONObject(this.getProp(Quiz.JSON_PROPERTY_FEEDBACK_HTML_FILE));
Iterator<?> keys = feedbackLangs.keys();

while (keys.hasNext()) {
String key = (String) keys.next();
this.setFeedbackHtmlForLang(key, feedbackLangs.getString(key));
}
} catch (JSONException e) {
this.setFeedbackHtmlForLang(defaultLang, this.getProp(Quiz.JSON_PROPERTY_FEEDBACK));
}
}

private void setFeedbackHtmlForLang(String lang, String title) {
this.feedbackHtml.put(lang, title);
}

public String getFeedbackHtml(String lang) {
if (feedbackHtml.containsKey(lang)) {
return feedbackHtml.get(lang);
} else if (!feedbackHtml.entrySet().isEmpty()) {
return feedbackHtml.entrySet().iterator().next().getValue();
} else {
return "";
}
}

public Float getTolerance() {
Float tolerance = (float) 0.0;
if(this.getProp(Quiz.JSON_PROPERTY_TOLERANCE) != null){
if (this.getProp(Quiz.JSON_PROPERTY_TOLERANCE) != null) {
tolerance = Float.parseFloat(this.getProp(Quiz.JSON_PROPERTY_TOLERANCE));
}
return tolerance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public class Description extends QuizQuestion {
private static final long serialVersionUID = 809312927290284785L;
public static final String TAG = Description.class.getSimpleName();

@Override
public void mark(String lang) {
// Nothing to do
}

@Override
public JSONObject responsesToJSON() {
JSONObject jo = new JSONObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,30 @@

package org.digitalcampus.mobile.quiz.model.questiontypes;

import org.digitalcampus.mobile.quiz.model.Response;

import java.io.Serializable;

public class MultiChoice extends UserResponseQuestion implements Serializable {

private static final long serialVersionUID = -6605393327170759582L;
public static final String TAG = MultiChoice.class.getSimpleName();

@Override
public void mark(String lang) {
// loop through the responses
// find whichever are set as selected and add up the responses
float total = 0;
for (Response r : responseOptions) {
for (String a : userResponses) {
if (r.getTitle(lang).equals(a)) {
total += r.getScore();
feedback = r.getFeedback(lang);
feedbackHtmlFile = r.getFeedbackHtml(lang);
}
}
}
this.calculateUserscore(total);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,37 @@ public void mark(String lang){
} else {
userscore = total;
}

setFeedbackHtmlFile(lang);
Log.d(TAG, "User score for question: " + userscore);
}

private void setFeedbackHtmlFile(String lang) {
try {
String feedbackKey = "";
if (userscore * 100 < Quiz.QUIZ_QUESTION_PASS_THRESHOLD) {
feedbackKey = "incorrectfeedbackhtmlfile";
} else {
feedbackKey = "correctfeedbackhtmlfile";
}

if (getProps().containsKey(feedbackKey)) {
String incorrectFeedbackLangs = getProps().get(feedbackKey);
JSONObject feedbackHtmlLangs = new JSONObject(incorrectFeedbackLangs);

if (feedbackHtmlLangs.has(lang)) {
feedbackHtmlFile = feedbackHtmlLangs.getString(lang);
} else if (feedbackHtmlLangs.keys().hasNext()) {
feedbackHtmlFile = feedbackHtmlLangs.getString(feedbackHtmlLangs.keys().next());
} else {
feedbackHtmlFile = "";
}
}
} catch (JSONException e) {
Log.e(TAG, "setFeedbackHtmlFile: ", e);
}
}

private float setFeedback(String lang){
float total = 0;
StringBuilder questionFeedback = new StringBuilder();
Expand Down
64 changes: 54 additions & 10 deletions app/src/main/java/org/digitalcampus/oppia/widgets/AnswerWidget.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

Expand All @@ -52,6 +52,7 @@
import org.digitalcampus.mobile.quiz.model.questiontypes.Numerical;
import org.digitalcampus.mobile.quiz.model.questiontypes.ShortAnswer;
import org.digitalcampus.oppia.activity.CourseActivity;
import org.digitalcampus.oppia.activity.PrefsActivity;
import org.digitalcampus.oppia.analytics.Analytics;
import org.digitalcampus.oppia.model.Activity;
import org.digitalcampus.oppia.model.Course;
Expand All @@ -60,6 +61,7 @@
import org.digitalcampus.oppia.utils.TextUtilsJava;
import org.digitalcampus.oppia.utils.UIUtils;
import org.digitalcampus.oppia.utils.resources.ExternalResourceOpener;
import org.digitalcampus.oppia.utils.storage.FileUtils;
import org.digitalcampus.oppia.utils.ui.ProgressBarAnimator;
import org.digitalcampus.oppia.utils.ui.SimpleAnimator;
import org.digitalcampus.oppia.widgets.quiz.DescriptionWidget;
Expand All @@ -72,11 +74,10 @@
import org.digitalcampus.oppia.widgets.quiz.ShortAnswerWidget;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.inject.Inject;

Expand Down Expand Up @@ -386,16 +387,25 @@ private void setNav() {

private View.OnClickListener nextBtnClickListener() {
return v -> {

UIUtils.hideSoftKeyboard(v);

// save answer
if (saveAnswer()) {
String feedback;
try {
feedback = quiz.getCurrentQuestion().getFeedback(prefLang);
if (!feedback.equals("") &&
quiz.getShowFeedback() == Quiz.SHOW_FEEDBACK_ALWAYS
if (quiz.getShowFeedback() == Quiz.SHOW_FEEDBACK_ALWAYS
&& !quiz.getCurrentQuestion().getFeedbackDisplayed()) {
UIUtils.hideSoftKeyboard(v);
showFeedback(feedback);

String feedback = quiz.getCurrentQuestion().getFeedback(prefLang);
String feedbackHtmlFile = quiz.getCurrentQuestion().getFeedbackHtmlFile(prefLang);

if (feedbackHtmlFile != null && !feedbackHtmlFile.isEmpty()) {
showFeedbackHtmlFile(feedbackHtmlFile);
} else if (feedback != null && !feedback.isEmpty()) {
showFeedback(feedback);
} else {
nextStep();
}
} else {
nextStep();
}
Expand Down Expand Up @@ -481,6 +491,40 @@ private void showFeedback(String msg) {
}
}

private void showFeedbackHtmlFile(String htmlFile) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.Oppia_AlertDialogStyle);
WebView webView = new WebView(getContext());
webView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
loadWebviewContents(webView, htmlFile);
builder.setView(webView);
builder.setPositiveButton(R.string.ok, (arg0, arg1) -> nextStep());
builder.show();

try {
quiz.getCurrentQuestion().setFeedbackDisplayed(true);
} catch (InvalidQuizException e) {
Analytics.logException(e);
Log.d(TAG, QUIZ_EXCEPTION_MESSAGE, e);
}
}

private void loadWebviewContents(WebView webview, String htmlFile) {

String url = course.getLocation() + htmlFile;
int defaultFontSize = Integer.parseInt(prefs.getString(PrefsActivity.PREF_TEXT_SIZE, "16"));

webview.getSettings().setDefaultFontSize(defaultFontSize);
webview.getSettings().setAllowFileAccess(true);

try {
String contents = FileUtils.readFile(url);
webview.getSettings().setJavaScriptEnabled(true);
webview.loadDataWithBaseURL("file://" + course.getLocation() + File.separator, contents, "text/html", "utf-8", null);
} catch (IOException e) {
webview.loadUrl("file://" + url);
}
}

public void showResults() {
clearMediaPlayer();
// log the activity as complete
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.digitalcampus.oppia.utils.resources.JSInterfaceForInlineInput;
import org.digitalcampus.oppia.utils.resources.JSInterfaceForResourceImages;
import org.digitalcampus.oppia.utils.storage.FileUtils;
import org.digitalcampus.oppia.utils.storage.Storage;

import java.io.BufferedReader;
import java.io.File;
Expand Down Expand Up @@ -159,6 +160,7 @@ public void onPageFinished(WebView view, String url) {
for (JSInterface jsInterface : jsInterfaces){
view.loadUrl(jsInterface.getJavascriptInjection());
}
view.evaluateJavascript("changeAudioSource('" + Storage.getMediaPath(getContext()) + "')", null);
}

// set up the page to intercept videos
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.digitalcampus.oppia.widgets.quiz;

import android.app.Activity;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
Expand Down Expand Up @@ -61,15 +62,22 @@ public void setQuestionResponses(List<Response> responses, List<String> currentA
Collections.shuffle(responses);
}

int id = 1000+1;
for (Response r : responses){
RadioButton rb = new RadioButton(ctx);
RadioGroup.LayoutParams params = new RadioGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
setResponseMarginInLayoutParams(params);
rb.setId(id);
rb.setText(UIUtils.getFromHtmlAndTrim(r.getTitle(currentUserLang)));
responsesRG.addView(rb, params);
String showStandardInstructions = question.getProp("show_standard_instructions");
View tvInstructions = view.findViewById(R.id.tv_instructions);
if (tvInstructions != null) {
boolean visible = showStandardInstructions != null && showStandardInstructions.equals("1");
tvInstructions.setVisibility(visible ? View.VISIBLE : View.GONE);
}

int id = 1000 + 1;
for (Response r : responses) {
RadioButton rb = new RadioButton(ctx);
RadioGroup.LayoutParams params = new RadioGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
setResponseMarginInLayoutParams(params);
rb.setId(id);
rb.setText(UIUtils.getFromHtmlAndTrim(r.getTitle(currentUserLang)));
responsesRG.addView(rb, params);
for (String answer : currentAnswer) {
if (answer.equals(r.getTitle(currentUserLang))){
rb.setChecked(true);
Expand Down
Loading