Skip to content

Commit 386bd0a

Browse files
author
Vivek Maskara
authored
Merge gamification branch with master (#1752)
* Quiz (#1629) * Layout inflated * Layout for mcq added * Inflated Basic Layout * Implemented basic flow * Added the basic implementation pf score * Added the result layout * Added the result layout * Added functionality to set result * Changed the launcher intent to Quiz Activity for testing purpose * Explanations of answers added * Improved the layout of quiz result a bit * Fixed some minor issues * Fixed build issues * Api Added and basic structure for calling implemented * Added intents * Added the title * Fixed image error and improved quality of pr * Made separate class for checking quiz * Added counter * Implemented back and next for quiz result * Added back functionality to quiz * Added progressBar * Fixed bugs * Improved code quality * Imporved code Quality * Updated strings * Added share screenshot function * Added checks and improved UI * Removed unused string * Removed unused string * Adding checks and improving code quality * Changed string * Improved code quality * Update strings.xml * Update MediaWikiApi.java * Fix build
1 parent 80068f7 commit 386bd0a

21 files changed

+1067
-8
lines changed

app/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ dependencies {
7676
debugImplementation "com.squareup.leakcanary:leakcanary-android:$LEAK_CANARY"
7777
releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$LEAK_CANARY"
7878
testImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$LEAK_CANARY"
79+
80+
implementation 'com.borjabravo:readmoretextview:2.1.0'
81+
implementation 'com.dinuscxj:circleprogressbar:1.1.1'
7982
}
8083

8184
android {

app/src/main/AndroidManifest.xml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<uses-permission android:name="android.permission.READ_LOGS"/>
1919
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
2020

21+
2122
<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
2223
<uses-feature android:name="android.hardware.location.gps" />
2324

@@ -36,6 +37,7 @@
3637
<activity android:name=".auth.LoginActivity">
3738
<intent-filter>
3839
<category android:name="android.intent.category.LAUNCHER" />
40+
3941
<action android:name="android.intent.action.MAIN" />
4042
</intent-filter>
4143
</activity>
@@ -93,6 +95,12 @@
9395
android:name=".notification.NotificationActivity"
9496
android:label="@string/navigation_item_notification" />
9597

98+
<activity android:name=".quiz.QuizActivity"
99+
android:label="@string/quiz"/>
100+
101+
<activity android:name=".quiz.QuizResultActivity"
102+
android:label="@string/result"/>
103+
96104
<activity
97105
android:name=".category.CategoryImagesActivity"
98106
android:label="@string/title_activity_featured_images"
@@ -121,7 +129,6 @@
121129
<intent-filter>
122130
<action android:name="android.accounts.AccountAuthenticator" />
123131
</intent-filter>
124-
125132
<meta-data
126133
android:name="android.accounts.AccountAuthenticator"
127134
android:resource="@xml/authenticator" />

app/src/main/java/fr/free/nrw/commons/WelcomeActivity.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import butterknife.BindView;
1111
import butterknife.ButterKnife;
12+
import fr.free.nrw.commons.quiz.QuizActivity;
1213
import fr.free.nrw.commons.theme.BaseActivity;
1314

1415
public class WelcomeActivity extends BaseActivity {
@@ -17,6 +18,7 @@ public class WelcomeActivity extends BaseActivity {
1718
@BindView(R.id.welcomePagerIndicator) CirclePageIndicator indicator;
1819

1920
private WelcomePagerAdapter adapter = new WelcomePagerAdapter();
21+
private boolean isQuiz;
2022

2123
/**
2224
* Initialises exiting fields and dependencies
@@ -28,6 +30,15 @@ public void onCreate(Bundle savedInstanceState) {
2830
super.onCreate(savedInstanceState);
2931
setContentView(R.layout.activity_welcome);
3032

33+
if(getIntent() != null) {
34+
Bundle bundle = getIntent().getExtras();
35+
if (bundle != null) {
36+
isQuiz = bundle.getBoolean("isQuiz");
37+
}
38+
} else{
39+
isQuiz = false;
40+
}
41+
3142
ButterKnife.bind(this);
3243

3344
pager.setAdapter(adapter);
@@ -40,6 +51,10 @@ public void onCreate(Bundle savedInstanceState) {
4051
*/
4152
@Override
4253
public void onDestroy() {
54+
if(isQuiz){
55+
Intent i = new Intent(WelcomeActivity.this, QuizActivity.class);
56+
startActivity(i);
57+
}
4358
adapter.setCallback(null);
4459
super.onDestroy();
4560
}

app/src/main/java/fr/free/nrw/commons/achievements/AchievementsActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ private void setAchievements() {
221221
private void setRevertCount(){
222222
if(checkAccount()) {
223223
compositeDisposable.add(mediaWikiApi
224-
.getRevertCount(sessionManager.getCurrentAccount().name)
224+
.getRevertRespObjectSingle(sessionManager.getCurrentAccount().name)
225225
.subscribeOn(Schedulers.io())
226226
.observeOn(AndroidSchedulers.mainThread())
227227
.subscribe(

app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package fr.free.nrw.commons.contributions;
22

3+
import android.accounts.Account;
34
import android.content.ComponentName;
45
import android.content.Context;
56
import android.content.Intent;
@@ -34,8 +35,10 @@
3435
import fr.free.nrw.commons.auth.SessionManager;
3536
import fr.free.nrw.commons.media.MediaDetailPagerFragment;
3637
import fr.free.nrw.commons.mwapi.MediaWikiApi;
38+
import fr.free.nrw.commons.quiz.QuizChecker;
3739
import fr.free.nrw.commons.settings.Prefs;
3840
import fr.free.nrw.commons.upload.UploadService;
41+
import fr.free.nrw.commons.utils.ViewUtil;
3942
import io.reactivex.android.schedulers.AndroidSchedulers;
4043
import io.reactivex.disposables.CompositeDisposable;
4144
import io.reactivex.schedulers.Schedulers;
@@ -137,10 +140,17 @@ protected void onCreate(Bundle savedInstanceState) {
137140

138141
getSupportLoaderManager().initLoader(0, null, this);
139142
}
143+
140144
requestAuthToken();
141145
initDrawer();
142146
setTitle(getString(R.string.title_activity_contributions));
143147

148+
149+
if(checkAccount()) {
150+
new QuizChecker(this,
151+
sessionManager.getCurrentAccount().name,
152+
mediaWikiApi);
153+
}
144154
if(!BuildConfig.FLAVOR.equalsIgnoreCase("beta")){
145155
setUploadCount();
146156
}
@@ -338,6 +348,21 @@ public void unregisterDataSetObserver(DataSetObserver observer) {
338348
}
339349
}
340350

351+
/**
352+
* to ensure user is logged in
353+
* @return
354+
*/
355+
private boolean checkAccount() {
356+
Account currentAccount = sessionManager.getCurrentAccount();
357+
if (currentAccount == null) {
358+
Timber.d("Current account is null");
359+
ViewUtil.showLongToast(this, getResources().getString(R.string.user_not_logged_in));
360+
sessionManager.forceLogin(this);
361+
return false;
362+
}
363+
return true;
364+
}
365+
341366
@Override
342367
public void onBackStackChanged() {
343368
initBackButton();

app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,7 @@ public Single<Integer> getUploadCount(String userName) {
894894
}
895895

896896
/**
897+
897898
* Checks to see if a user is currently blocked from Commons
898899
* @return whether or not the user is blocked from Commons
899900
*/
@@ -964,7 +965,7 @@ public Single<JSONObject> getAchievements(String userName) {
964965
*/
965966
@NonNull
966967
@Override
967-
public Single<JSONObject> getRevertCount(String userName){
968+
public Single<JSONObject> getRevertRespObjectSingle(String userName){
968969
final String fetchRevertCountUrlTemplate =
969970
wikiMediaToolforgeUrl + "urbanecmbot/commonsmisc/feedback.py";
970971
return Single.fromCallable(() -> {

app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,14 @@ public interface MediaWikiApi {
9797
@NonNull
9898
Single<Integer> getUploadCount(String userName);
9999

100+
@NonNull
101+
Single<JSONObject> getRevertRespObjectSingle(String userName);
102+
100103
boolean isUserBlockedFromCommons();
101104

102105
@NonNull
103106
Single<JSONObject> getAchievements(String userName);
104107

105-
@NonNull
106-
Single<JSONObject> getRevertCount(String userName);
107-
108108
interface ProgressListener {
109109
void onProgress(long transferred, long total);
110110
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package fr.free.nrw.commons.quiz;
2+
3+
import android.content.Context;
4+
import android.content.DialogInterface;
5+
import android.content.Intent;
6+
import android.os.Bundle;
7+
import android.support.graphics.drawable.VectorDrawableCompat;
8+
import android.support.v7.app.AlertDialog;
9+
import android.support.v7.app.AppCompatActivity;
10+
import android.support.v7.widget.Toolbar;
11+
import android.view.View;
12+
import android.widget.ProgressBar;
13+
import android.widget.RadioButton;
14+
import android.widget.TextView;
15+
16+
import com.facebook.drawee.backends.pipeline.Fresco;
17+
import com.facebook.drawee.drawable.ProgressBarDrawable;
18+
import com.facebook.drawee.generic.GenericDraweeHierarchy;
19+
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
20+
import com.facebook.drawee.view.SimpleDraweeView;
21+
22+
import java.util.ArrayList;
23+
24+
import butterknife.BindView;
25+
import butterknife.ButterKnife;
26+
import butterknife.OnClick;
27+
import fr.free.nrw.commons.R;
28+
import fr.free.nrw.commons.contributions.ContributionsActivity;
29+
30+
public class QuizActivity extends AppCompatActivity {
31+
32+
@BindView(R.id.question_image) SimpleDraweeView imageView;
33+
@BindView(R.id.question_text) TextView questionText;
34+
@BindView(R.id.question_title) TextView questionTitle;
35+
@BindView(R.id.quiz_positive_answer) RadioButton positiveAnswer;
36+
@BindView(R.id.quiz_negative_answer) RadioButton negativeAnswer;
37+
@BindView(R.id.toolbar) Toolbar toolbar;
38+
39+
private QuizController quizController = new QuizController();
40+
private ArrayList<QuizQuestion> quiz = new ArrayList<QuizQuestion>();
41+
private int questionIndex = 0;
42+
private int score;
43+
44+
@Override
45+
protected void onCreate(Bundle savedInstanceState) {
46+
super.onCreate(savedInstanceState);
47+
setContentView(R.layout.activity_quiz);
48+
Fresco.initialize(this);
49+
50+
quizController.initialize(this);
51+
ButterKnife.bind(this);
52+
setSupportActionBar(toolbar);
53+
displayQuestion();
54+
}
55+
56+
/**
57+
* to move to next question and check whether answer is selected or not
58+
*/
59+
@OnClick(R.id.next_button)
60+
public void setNextQuestion(){
61+
if( questionIndex <= quiz.size() && (positiveAnswer.isChecked() || negativeAnswer.isChecked())) {
62+
evaluateScore();
63+
} else if ( !positiveAnswer.isChecked() && !negativeAnswer.isChecked()){
64+
AlertDialog.Builder alert = new AlertDialog.Builder(this);
65+
alert.setTitle(getResources().getString(R.string.warning));
66+
alert.setMessage(getResources().getString(R.string.warning_for_no_answer));
67+
alert.setPositiveButton(R.string.continue_message, new DialogInterface.OnClickListener() {
68+
@Override
69+
public void onClick(DialogInterface dialog, int which) {
70+
dialog.dismiss();
71+
}
72+
});
73+
AlertDialog dialog = alert.create();
74+
dialog.show();
75+
}
76+
77+
}
78+
79+
/**
80+
* to give warning before ending quiz
81+
*/
82+
@Override
83+
public void onBackPressed() {
84+
AlertDialog.Builder alert = new AlertDialog.Builder(this);
85+
alert.setTitle(getResources().getString(R.string.warning));
86+
alert.setMessage(getResources().getString(R.string.quiz_back_button));
87+
alert.setPositiveButton(R.string.continue_message, new DialogInterface.OnClickListener() {
88+
@Override
89+
public void onClick(DialogInterface dialog, int which) {
90+
Intent i = new Intent(QuizActivity.this, QuizResultActivity.class);
91+
dialog.dismiss();
92+
i.putExtra("QuizResult",score);
93+
startActivity(i);
94+
}
95+
});
96+
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
97+
@Override
98+
public void onClick(DialogInterface dialogInterface, int i) {
99+
dialogInterface.dismiss();
100+
}
101+
});
102+
AlertDialog dialog = alert.create();
103+
dialog.show();
104+
}
105+
106+
/**
107+
* to display the question
108+
*/
109+
public void displayQuestion() {
110+
quiz = quizController.getQuiz();
111+
questionText.setText(quiz.get(questionIndex).getQuestion());
112+
questionTitle.setText(getResources().getString(R.string.question)+quiz.get(questionIndex).getQuestionNumber());
113+
imageView.setHierarchy(GenericDraweeHierarchyBuilder
114+
.newInstance(getResources())
115+
.setFailureImage(VectorDrawableCompat.create(getResources(),
116+
R.drawable.ic_error_outline_black_24dp, getTheme()))
117+
.setProgressBarImage(new ProgressBarDrawable())
118+
.build());
119+
120+
imageView.setImageURI(quiz.get(questionIndex).getUrl());
121+
new RadioGroupHelper(this, R.id.quiz_positive_answer, R.id.quiz_negative_answer);
122+
positiveAnswer.setChecked(false);
123+
negativeAnswer.setChecked(false);
124+
}
125+
126+
/**
127+
* to evaluate score and check whether answer is correct or wrong
128+
*/
129+
public void evaluateScore() {
130+
if((quiz.get(questionIndex).isAnswer() && positiveAnswer.isChecked()) ||
131+
(!quiz.get(questionIndex).isAnswer() && negativeAnswer.isChecked()) ){
132+
customAlert(getResources().getString(R.string.correct),quiz.get(questionIndex).getAnswerMessage() );
133+
score++;
134+
} else{
135+
customAlert(getResources().getString(R.string.wrong), quiz.get(questionIndex).getAnswerMessage());
136+
}
137+
}
138+
139+
/**
140+
* to display explanation after each answer, update questionIndex and move to next question
141+
* @param title
142+
* @param Message
143+
*/
144+
public void customAlert(String title, String Message) {
145+
AlertDialog.Builder alert = new AlertDialog.Builder(this);
146+
alert.setTitle(title);
147+
alert.setMessage(Message);
148+
alert.setPositiveButton(R.string.continue_message, new DialogInterface.OnClickListener() {
149+
@Override
150+
public void onClick(DialogInterface dialog, int which) {
151+
questionIndex++;
152+
if(questionIndex == quiz.size()){
153+
Intent i = new Intent(QuizActivity.this, QuizResultActivity.class);
154+
dialog.dismiss();
155+
i.putExtra("QuizResult",score);
156+
startActivity(i);
157+
}else {
158+
displayQuestion();
159+
}
160+
}
161+
});
162+
AlertDialog dialog = alert.create();
163+
dialog.show();
164+
}
165+
}

0 commit comments

Comments
 (0)