mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Migrated quiz module from Java to Kotlin (#5952)
* Rename .java to .kt * Migrated quiz module to Kotlin * unit test failing fixed * unit test failing fixed
This commit is contained in:
parent
bafae821e2
commit
00cfd83521
10 changed files with 658 additions and 628 deletions
|
|
@ -1,146 +0,0 @@
|
|||
package fr.free.nrw.commons.quiz;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
|
||||
|
||||
import com.facebook.drawee.drawable.ProgressBarDrawable;
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
|
||||
|
||||
import fr.free.nrw.commons.databinding.ActivityQuizBinding;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
|
||||
public class QuizActivity extends AppCompatActivity {
|
||||
|
||||
private ActivityQuizBinding binding;
|
||||
private final QuizController quizController = new QuizController();
|
||||
private ArrayList<QuizQuestion> quiz = new ArrayList<>();
|
||||
private int questionIndex = 0;
|
||||
private int score;
|
||||
/**
|
||||
* isPositiveAnswerChecked : represents yes click event
|
||||
*/
|
||||
private boolean isPositiveAnswerChecked;
|
||||
/**
|
||||
* isNegativeAnswerChecked : represents no click event
|
||||
*/
|
||||
private boolean isNegativeAnswerChecked;
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = ActivityQuizBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
quizController.initialize(this);
|
||||
setSupportActionBar(binding.toolbar.toolbar);
|
||||
binding.nextButton.setOnClickListener(view -> notKnowAnswer());
|
||||
displayQuestion();
|
||||
}
|
||||
|
||||
/**
|
||||
* to move to next question and check whether answer is selected or not
|
||||
*/
|
||||
public void setNextQuestion(){
|
||||
if ( questionIndex <= quiz.size() && (isPositiveAnswerChecked || isNegativeAnswerChecked)) {
|
||||
evaluateScore();
|
||||
}
|
||||
}
|
||||
|
||||
public void notKnowAnswer(){
|
||||
customAlert("Information", quiz.get(questionIndex).getAnswerMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* to give warning before ending quiz
|
||||
*/
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(getResources().getString(R.string.warning))
|
||||
.setMessage(getResources().getString(R.string.quiz_back_button))
|
||||
.setPositiveButton(R.string.continue_message, (dialog, which) -> {
|
||||
final Intent intent = new Intent(this, QuizResultActivity.class);
|
||||
dialog.dismiss();
|
||||
intent.putExtra("QuizResult", score);
|
||||
startActivity(intent);
|
||||
})
|
||||
.setNegativeButton("Cancel", (dialogInterface, i) -> dialogInterface.dismiss())
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* to display the question
|
||||
*/
|
||||
public void displayQuestion() {
|
||||
quiz = quizController.getQuiz();
|
||||
binding.question.questionText.setText(quiz.get(questionIndex).getQuestion());
|
||||
binding.questionTitle.setText(
|
||||
getResources().getString(R.string.question) +
|
||||
quiz.get(questionIndex).getQuestionNumber()
|
||||
);
|
||||
binding.question.questionImage.setHierarchy(GenericDraweeHierarchyBuilder
|
||||
.newInstance(getResources())
|
||||
.setFailureImage(VectorDrawableCompat.create(getResources(),
|
||||
R.drawable.ic_error_outline_black_24dp, getTheme()))
|
||||
.setProgressBarImage(new ProgressBarDrawable())
|
||||
.build());
|
||||
|
||||
binding.question.questionImage.setImageURI(quiz.get(questionIndex).getUrl());
|
||||
isPositiveAnswerChecked = false;
|
||||
isNegativeAnswerChecked = false;
|
||||
binding.answer.quizPositiveAnswer.setOnClickListener(view -> {
|
||||
isPositiveAnswerChecked = true;
|
||||
setNextQuestion();
|
||||
});
|
||||
binding.answer.quizNegativeAnswer.setOnClickListener(view -> {
|
||||
isNegativeAnswerChecked = true;
|
||||
setNextQuestion();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* to evaluate score and check whether answer is correct or wrong
|
||||
*/
|
||||
public void evaluateScore() {
|
||||
if ((quiz.get(questionIndex).isAnswer() && isPositiveAnswerChecked) ||
|
||||
(!quiz.get(questionIndex).isAnswer() && isNegativeAnswerChecked) ){
|
||||
customAlert(getResources().getString(R.string.correct),
|
||||
quiz.get(questionIndex).getAnswerMessage());
|
||||
score++;
|
||||
} else {
|
||||
customAlert(getResources().getString(R.string.wrong),
|
||||
quiz.get(questionIndex).getAnswerMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* to display explanation after each answer, update questionIndex and move to next question
|
||||
* @param title the alert title
|
||||
* @param Message the alert message
|
||||
*/
|
||||
public void customAlert(final String title, final String Message) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(title)
|
||||
.setMessage(Message)
|
||||
.setPositiveButton(R.string.continue_message, (dialog, which) -> {
|
||||
questionIndex++;
|
||||
if (questionIndex == quiz.size()) {
|
||||
final Intent intent = new Intent(this, QuizResultActivity.class);
|
||||
dialog.dismiss();
|
||||
intent.putExtra("QuizResult", score);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
displayQuestion();
|
||||
}
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
}
|
||||
154
app/src/main/java/fr/free/nrw/commons/quiz/QuizActivity.kt
Normal file
154
app/src/main/java/fr/free/nrw/commons/quiz/QuizActivity.kt
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
package fr.free.nrw.commons.quiz
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||
|
||||
import com.facebook.drawee.drawable.ProgressBarDrawable
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
|
||||
|
||||
import fr.free.nrw.commons.databinding.ActivityQuizBinding
|
||||
import java.util.ArrayList
|
||||
|
||||
import fr.free.nrw.commons.R
|
||||
|
||||
|
||||
class QuizActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityQuizBinding
|
||||
private val quizController = QuizController()
|
||||
private var quiz = ArrayList<QuizQuestion>()
|
||||
private var questionIndex = 0
|
||||
private var score = 0
|
||||
|
||||
/**
|
||||
* isPositiveAnswerChecked : represents yes click event
|
||||
*/
|
||||
private var isPositiveAnswerChecked = false
|
||||
|
||||
/**
|
||||
* isNegativeAnswerChecked : represents no click event
|
||||
*/
|
||||
private var isNegativeAnswerChecked = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityQuizBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
quizController.initialize(this)
|
||||
setSupportActionBar(binding.toolbar.toolbar)
|
||||
binding.nextButton.setOnClickListener { notKnowAnswer() }
|
||||
displayQuestion()
|
||||
}
|
||||
|
||||
/**
|
||||
* To move to next question and check whether answer is selected or not
|
||||
*/
|
||||
fun setNextQuestion() {
|
||||
if (questionIndex <= quiz.size && (isPositiveAnswerChecked || isNegativeAnswerChecked)) {
|
||||
evaluateScore()
|
||||
}
|
||||
}
|
||||
|
||||
private fun notKnowAnswer() {
|
||||
customAlert("Information", quiz[questionIndex].answerMessage)
|
||||
}
|
||||
|
||||
/**
|
||||
* To give warning before ending quiz
|
||||
*/
|
||||
override fun onBackPressed() {
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(getString(R.string.warning))
|
||||
.setMessage(getString(R.string.quiz_back_button))
|
||||
.setPositiveButton(R.string.continue_message) { dialog, _ ->
|
||||
val intent = Intent(this, QuizResultActivity::class.java)
|
||||
dialog.dismiss()
|
||||
intent.putExtra("QuizResult", score)
|
||||
startActivity(intent)
|
||||
}
|
||||
.setNegativeButton("Cancel") { dialogInterface, _ -> dialogInterface.dismiss() }
|
||||
.create()
|
||||
.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* To display the question
|
||||
*/
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun displayQuestion() {
|
||||
quiz = quizController.getQuiz()
|
||||
binding.question.questionText.text = quiz[questionIndex].question
|
||||
binding.questionTitle.text = getString(R.string.question) + quiz[questionIndex].questionNumber
|
||||
|
||||
binding.question.questionImage.hierarchy = GenericDraweeHierarchyBuilder
|
||||
.newInstance(resources)
|
||||
.setFailureImage(VectorDrawableCompat.create(resources, R.drawable.ic_error_outline_black_24dp, theme))
|
||||
.setProgressBarImage(ProgressBarDrawable())
|
||||
.build()
|
||||
|
||||
binding.question.questionImage.setImageURI(quiz[questionIndex].getUrl())
|
||||
isPositiveAnswerChecked = false
|
||||
isNegativeAnswerChecked = false
|
||||
|
||||
binding.answer.quizPositiveAnswer.setOnClickListener {
|
||||
isPositiveAnswerChecked = true
|
||||
setNextQuestion()
|
||||
}
|
||||
binding.answer.quizNegativeAnswer.setOnClickListener {
|
||||
isNegativeAnswerChecked = true
|
||||
setNextQuestion()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To evaluate score and check whether answer is correct or wrong
|
||||
*/
|
||||
fun evaluateScore() {
|
||||
if (
|
||||
(quiz[questionIndex].isAnswer && isPositiveAnswerChecked)
|
||||
||
|
||||
(!quiz[questionIndex].isAnswer && isNegativeAnswerChecked)
|
||||
) {
|
||||
customAlert(
|
||||
getString(R.string.correct),
|
||||
quiz[questionIndex].answerMessage
|
||||
)
|
||||
score++
|
||||
} else {
|
||||
customAlert(
|
||||
getString(R.string.wrong),
|
||||
quiz[questionIndex].answerMessage
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To display explanation after each answer, update questionIndex and move to next question
|
||||
* @param title The alert title
|
||||
* @param message The alert message
|
||||
*/
|
||||
fun customAlert(title: String, message: String) {
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(title)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.continue_message) { dialog, _ ->
|
||||
questionIndex++
|
||||
if (questionIndex == quiz.size) {
|
||||
val intent = Intent(this, QuizResultActivity::class.java)
|
||||
dialog.dismiss()
|
||||
intent.putExtra("QuizResult", score)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
displayQuestion()
|
||||
}
|
||||
}
|
||||
.create()
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
package fr.free.nrw.commons.quiz;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.WelcomeActivity;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
|
||||
import fr.free.nrw.commons.utils.DialogUtil;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* fetches the number of images uploaded and number of images reverted.
|
||||
* Then it calculates the percentage of the images reverted
|
||||
* if the percentage of images reverted after last quiz exceeds 50% and number of images uploaded is
|
||||
* greater than 50, then quiz is popped up
|
||||
*/
|
||||
@Singleton
|
||||
public class QuizChecker {
|
||||
|
||||
private int revertCount ;
|
||||
private int totalUploadCount ;
|
||||
private boolean isRevertCountFetched;
|
||||
private boolean isUploadCountFetched;
|
||||
|
||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
|
||||
private final SessionManager sessionManager;
|
||||
private final OkHttpJsonApiClient okHttpJsonApiClient;
|
||||
private final JsonKvStore revertKvStore;
|
||||
|
||||
private static final int UPLOAD_COUNT_THRESHOLD = 5;
|
||||
private static final String REVERT_PERCENTAGE_FOR_MESSAGE = "50%";
|
||||
private final String REVERT_SHARED_PREFERENCE = "revertCount";
|
||||
private final String UPLOAD_SHARED_PREFERENCE = "uploadCount";
|
||||
|
||||
/**
|
||||
* constructor to set the parameters for quiz
|
||||
* @param sessionManager
|
||||
* @param okHttpJsonApiClient
|
||||
*/
|
||||
@Inject
|
||||
public QuizChecker(SessionManager sessionManager,
|
||||
OkHttpJsonApiClient okHttpJsonApiClient,
|
||||
@Named("default_preferences") JsonKvStore revertKvStore) {
|
||||
this.sessionManager = sessionManager;
|
||||
this.okHttpJsonApiClient = okHttpJsonApiClient;
|
||||
this.revertKvStore = revertKvStore;
|
||||
}
|
||||
|
||||
public void initQuizCheck(Activity activity) {
|
||||
calculateRevertParameterAndShowQuiz(activity);
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
compositeDisposable.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* to fet the total number of images uploaded
|
||||
*/
|
||||
private void setUploadCount() {
|
||||
compositeDisposable.add(okHttpJsonApiClient
|
||||
.getUploadCount(sessionManager.getUserName())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::setTotalUploadCount,
|
||||
t -> Timber.e(t, "Fetching upload count failed")
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* set the sub Title of Contibutions Activity and
|
||||
* call function to check for quiz
|
||||
* @param uploadCount user's upload count
|
||||
*/
|
||||
private void setTotalUploadCount(int uploadCount) {
|
||||
totalUploadCount = uploadCount - revertKvStore.getInt(UPLOAD_SHARED_PREFERENCE, 0);
|
||||
if ( totalUploadCount < 0){
|
||||
totalUploadCount = 0;
|
||||
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, 0);
|
||||
}
|
||||
isUploadCountFetched = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* To call the API to get reverts count in form of JSONObject
|
||||
*/
|
||||
private void setRevertCount() {
|
||||
compositeDisposable.add(okHttpJsonApiClient
|
||||
.getAchievements(sessionManager.getUserName())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
response -> {
|
||||
if (response != null) {
|
||||
setRevertParameter(response.getDeletedUploads());
|
||||
}
|
||||
}, throwable -> Timber.e(throwable, "Fetching feedback failed"))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* to calculate the number of images reverted after previous quiz
|
||||
* @param revertCountFetched count of deleted uploads
|
||||
*/
|
||||
private void setRevertParameter(int revertCountFetched) {
|
||||
revertCount = revertCountFetched - revertKvStore.getInt(REVERT_SHARED_PREFERENCE, 0);
|
||||
if (revertCount < 0){
|
||||
revertCount = 0;
|
||||
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, 0);
|
||||
}
|
||||
isRevertCountFetched = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* to check whether the criterion to call quiz is satisfied
|
||||
*/
|
||||
private void calculateRevertParameterAndShowQuiz(Activity activity) {
|
||||
setUploadCount();
|
||||
setRevertCount();
|
||||
if ( revertCount < 0 || totalUploadCount < 0){
|
||||
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, 0);
|
||||
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, 0);
|
||||
return;
|
||||
}
|
||||
if (isRevertCountFetched && isUploadCountFetched &&
|
||||
totalUploadCount >= UPLOAD_COUNT_THRESHOLD &&
|
||||
(revertCount * 100) / totalUploadCount >= 50) {
|
||||
callQuiz(activity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert which prompts to quiz
|
||||
*/
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
private void callQuiz(Activity activity) {
|
||||
DialogUtil.showAlertDialog(activity,
|
||||
activity.getString(R.string.quiz),
|
||||
activity.getString(R.string.quiz_alert_message, REVERT_PERCENTAGE_FOR_MESSAGE),
|
||||
activity.getString(R.string.about_translate_proceed),
|
||||
activity.getString(android.R.string.cancel),
|
||||
() -> startQuizActivity(activity),
|
||||
null);
|
||||
}
|
||||
|
||||
private void startQuizActivity(Activity activity) {
|
||||
int newRevetSharedPrefs = revertCount + revertKvStore.getInt(REVERT_SHARED_PREFERENCE, 0);
|
||||
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, newRevetSharedPrefs);
|
||||
int newUploadCount = totalUploadCount + revertKvStore.getInt(UPLOAD_SHARED_PREFERENCE, 0);
|
||||
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, newUploadCount);
|
||||
Intent i = new Intent(activity, WelcomeActivity.class);
|
||||
i.putExtra("isQuiz", true);
|
||||
activity.startActivity(i);
|
||||
}
|
||||
}
|
||||
175
app/src/main/java/fr/free/nrw/commons/quiz/QuizChecker.kt
Normal file
175
app/src/main/java/fr/free/nrw/commons/quiz/QuizChecker.kt
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
package fr.free.nrw.commons.quiz
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.WelcomeActivity
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore
|
||||
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
|
||||
import fr.free.nrw.commons.utils.DialogUtil
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import timber.log.Timber
|
||||
|
||||
|
||||
/**
|
||||
* Fetches the number of images uploaded and number of images reverted.
|
||||
* Then it calculates the percentage of the images reverted.
|
||||
* If the percentage of images reverted after the last quiz exceeds 50% and number of images uploaded is
|
||||
* greater than 50, then the quiz is popped up.
|
||||
*/
|
||||
@Singleton
|
||||
class QuizChecker @Inject constructor(
|
||||
private val sessionManager: SessionManager,
|
||||
private val okHttpJsonApiClient: OkHttpJsonApiClient,
|
||||
@Named("default_preferences") private val revertKvStore: JsonKvStore
|
||||
) {
|
||||
|
||||
private var revertCount = 0
|
||||
private var totalUploadCount = 0
|
||||
private var isRevertCountFetched = false
|
||||
private var isUploadCountFetched = false
|
||||
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
|
||||
private val UPLOAD_COUNT_THRESHOLD = 5
|
||||
private val REVERT_PERCENTAGE_FOR_MESSAGE = "50%"
|
||||
private val REVERT_SHARED_PREFERENCE = "revertCount"
|
||||
private val UPLOAD_SHARED_PREFERENCE = "uploadCount"
|
||||
|
||||
/**
|
||||
* Initializes quiz check by calculating revert parameters and showing quiz if necessary
|
||||
*/
|
||||
fun initQuizCheck(activity: Activity) {
|
||||
calculateRevertParameterAndShowQuiz(activity)
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears disposables to avoid memory leaks
|
||||
*/
|
||||
fun cleanup() {
|
||||
compositeDisposable.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the total number of images uploaded
|
||||
*/
|
||||
private fun setUploadCount() {
|
||||
compositeDisposable.add(
|
||||
okHttpJsonApiClient.getUploadCount(sessionManager.userName)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ uploadCount -> setTotalUploadCount(uploadCount) },
|
||||
{ t -> Timber.e(t, "Fetching upload count failed") }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total upload count after subtracting stored preference
|
||||
* @param uploadCount User's upload count
|
||||
*/
|
||||
private fun setTotalUploadCount(uploadCount: Int) {
|
||||
totalUploadCount = uploadCount - revertKvStore.getInt(
|
||||
UPLOAD_SHARED_PREFERENCE,
|
||||
0
|
||||
)
|
||||
if (totalUploadCount < 0) {
|
||||
totalUploadCount = 0
|
||||
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, 0)
|
||||
}
|
||||
isUploadCountFetched = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the revert count using the API
|
||||
*/
|
||||
private fun setRevertCount() {
|
||||
compositeDisposable.add(
|
||||
okHttpJsonApiClient.getAchievements(sessionManager.userName)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ response ->
|
||||
response?.let { setRevertParameter(it.deletedUploads) }
|
||||
},
|
||||
{ throwable -> Timber.e(throwable, "Fetching feedback failed") }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of images reverted after the previous quiz
|
||||
* @param revertCountFetched Count of deleted uploads
|
||||
*/
|
||||
private fun setRevertParameter(revertCountFetched: Int) {
|
||||
revertCount = revertCountFetched - revertKvStore.getInt(REVERT_SHARED_PREFERENCE, 0)
|
||||
if (revertCount < 0) {
|
||||
revertCount = 0
|
||||
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, 0)
|
||||
}
|
||||
isRevertCountFetched = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the criteria for calling the quiz are satisfied
|
||||
*/
|
||||
private fun calculateRevertParameterAndShowQuiz(activity: Activity) {
|
||||
setUploadCount()
|
||||
setRevertCount()
|
||||
|
||||
if (revertCount < 0 || totalUploadCount < 0) {
|
||||
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, 0)
|
||||
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, 0)
|
||||
return
|
||||
}
|
||||
|
||||
if (isRevertCountFetched && isUploadCountFetched &&
|
||||
totalUploadCount >= UPLOAD_COUNT_THRESHOLD &&
|
||||
(revertCount * 100) / totalUploadCount >= 50
|
||||
) {
|
||||
callQuiz(activity)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an alert prompting the user to take the quiz
|
||||
*/
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
private fun callQuiz(activity: Activity) {
|
||||
DialogUtil.showAlertDialog(
|
||||
activity,
|
||||
activity.getString(R.string.quiz),
|
||||
activity.getString(R.string.quiz_alert_message, REVERT_PERCENTAGE_FOR_MESSAGE),
|
||||
activity.getString(R.string.about_translate_proceed),
|
||||
activity.getString(android.R.string.cancel),
|
||||
{ startQuizActivity(activity) },
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the quiz activity and updates preferences for revert and upload counts
|
||||
*/
|
||||
private fun startQuizActivity(activity: Activity) {
|
||||
val newRevertSharedPrefs = revertCount + revertKvStore.getInt(REVERT_SHARED_PREFERENCE, 0)
|
||||
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, newRevertSharedPrefs)
|
||||
|
||||
val newUploadCount = totalUploadCount + revertKvStore.getInt(UPLOAD_SHARED_PREFERENCE, 0)
|
||||
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, newUploadCount)
|
||||
|
||||
val intent = Intent(activity, WelcomeActivity::class.java).apply {
|
||||
putExtra("isQuiz", true)
|
||||
}
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
package fr.free.nrw.commons.quiz;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
|
||||
/**
|
||||
* controls the quiz in the Activity
|
||||
*/
|
||||
public class QuizController {
|
||||
|
||||
ArrayList<QuizQuestion> quiz = new ArrayList<>();
|
||||
|
||||
private final String URL_FOR_SELFIE = "https://i.imgur.com/0fMYcpM.jpg";
|
||||
private final String URL_FOR_TAJ_MAHAL = "https://upload.wikimedia.org/wikipedia/commons/1/15/Taj_Mahal-03.jpg";
|
||||
private final String URL_FOR_BLURRY_IMAGE = "https://i.imgur.com/Kepb5jR.jpg";
|
||||
private final String URL_FOR_SCREENSHOT = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8b/Social_media_app_mockup_screenshot.svg/500px-Social_media_app_mockup_screenshot.svg.png";
|
||||
private final String URL_FOR_EVENT = "https://upload.wikimedia.org/wikipedia/commons/5/51/HouseBuildingInNorthernVietnam.jpg";
|
||||
|
||||
public void initialize(Context context){
|
||||
QuizQuestion q1 = new QuizQuestion(1,
|
||||
context.getString(R.string.quiz_question_string),
|
||||
URL_FOR_SELFIE,
|
||||
false,
|
||||
context.getString(R.string.selfie_answer));
|
||||
quiz.add(q1);
|
||||
|
||||
QuizQuestion q2 = new QuizQuestion(2,
|
||||
context.getString(R.string.quiz_question_string),
|
||||
URL_FOR_TAJ_MAHAL,
|
||||
true,
|
||||
context.getString(R.string.taj_mahal_answer));
|
||||
quiz.add(q2);
|
||||
|
||||
QuizQuestion q3 = new QuizQuestion(3,
|
||||
context.getString(R.string.quiz_question_string),
|
||||
URL_FOR_BLURRY_IMAGE,
|
||||
false,
|
||||
context.getString(R.string.blurry_image_answer));
|
||||
quiz.add(q3);
|
||||
|
||||
QuizQuestion q4 = new QuizQuestion(4,
|
||||
context.getString(R.string.quiz_screenshot_question),
|
||||
URL_FOR_SCREENSHOT,
|
||||
false,
|
||||
context.getString(R.string.screenshot_answer));
|
||||
quiz.add(q4);
|
||||
|
||||
QuizQuestion q5 = new QuizQuestion(5,
|
||||
context.getString(R.string.quiz_question_string),
|
||||
URL_FOR_EVENT,
|
||||
true,
|
||||
context.getString(R.string.construction_event_answer));
|
||||
quiz.add(q5);
|
||||
|
||||
}
|
||||
|
||||
public ArrayList<QuizQuestion> getQuiz() {
|
||||
return quiz;
|
||||
}
|
||||
}
|
||||
76
app/src/main/java/fr/free/nrw/commons/quiz/QuizController.kt
Normal file
76
app/src/main/java/fr/free/nrw/commons/quiz/QuizController.kt
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
package fr.free.nrw.commons.quiz
|
||||
|
||||
import android.content.Context
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
import fr.free.nrw.commons.R
|
||||
|
||||
|
||||
/**
|
||||
* Controls the quiz in the Activity
|
||||
*/
|
||||
class QuizController {
|
||||
|
||||
private val quiz: ArrayList<QuizQuestion> = ArrayList()
|
||||
|
||||
private val URL_FOR_SELFIE = "https://i.imgur.com/0fMYcpM.jpg"
|
||||
private val URL_FOR_TAJ_MAHAL = "https://upload.wikimedia.org/wikipedia/commons/1/15/Taj_Mahal-03.jpg"
|
||||
private val URL_FOR_BLURRY_IMAGE = "https://i.imgur.com/Kepb5jR.jpg"
|
||||
private val URL_FOR_SCREENSHOT = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8b/Social_media_app_mockup_screenshot.svg/500px-Social_media_app_mockup_screenshot.svg.png"
|
||||
private val URL_FOR_EVENT = "https://upload.wikimedia.org/wikipedia/commons/5/51/HouseBuildingInNorthernVietnam.jpg"
|
||||
|
||||
fun initialize(context: Context) {
|
||||
val q1 = QuizQuestion(
|
||||
1,
|
||||
context.getString(R.string.quiz_question_string),
|
||||
URL_FOR_SELFIE,
|
||||
false,
|
||||
context.getString(R.string.selfie_answer)
|
||||
)
|
||||
quiz.add(q1)
|
||||
|
||||
val q2 = QuizQuestion(
|
||||
2,
|
||||
context.getString(R.string.quiz_question_string),
|
||||
URL_FOR_TAJ_MAHAL,
|
||||
true,
|
||||
context.getString(R.string.taj_mahal_answer)
|
||||
)
|
||||
quiz.add(q2)
|
||||
|
||||
val q3 = QuizQuestion(
|
||||
3,
|
||||
context.getString(R.string.quiz_question_string),
|
||||
URL_FOR_BLURRY_IMAGE,
|
||||
false,
|
||||
context.getString(R.string.blurry_image_answer)
|
||||
)
|
||||
quiz.add(q3)
|
||||
|
||||
val q4 = QuizQuestion(
|
||||
4,
|
||||
context.getString(R.string.quiz_screenshot_question),
|
||||
URL_FOR_SCREENSHOT,
|
||||
false,
|
||||
context.getString(R.string.screenshot_answer)
|
||||
)
|
||||
quiz.add(q4)
|
||||
|
||||
val q5 = QuizQuestion(
|
||||
5,
|
||||
context.getString(R.string.quiz_question_string),
|
||||
URL_FOR_EVENT,
|
||||
true,
|
||||
context.getString(R.string.construction_event_answer)
|
||||
)
|
||||
quiz.add(q5)
|
||||
}
|
||||
|
||||
fun getQuiz(): ArrayList<QuizQuestion> {
|
||||
return quiz
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
package fr.free.nrw.commons.quiz;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import fr.free.nrw.commons.databinding.ActivityQuizResultBinding;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.contributions.MainActivity;
|
||||
|
||||
|
||||
/**
|
||||
* Displays the final score of quiz and congratulates the user
|
||||
*/
|
||||
public class QuizResultActivity extends AppCompatActivity {
|
||||
|
||||
private ActivityQuizResultBinding binding;
|
||||
private final int NUMBER_OF_QUESTIONS = 5;
|
||||
private final int MULTIPLIER_TO_GET_PERCENTAGE = 20;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = ActivityQuizResultBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
setSupportActionBar(binding.toolbar.toolbar);
|
||||
|
||||
binding.quizResultNext.setOnClickListener(view -> launchContributionActivity());
|
||||
|
||||
if ( getIntent() != null) {
|
||||
Bundle extras = getIntent().getExtras();
|
||||
int score = extras.getInt("QuizResult");
|
||||
setScore(score);
|
||||
}else{
|
||||
startActivityWithFlags(
|
||||
this, MainActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP,
|
||||
Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
binding = null;
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* to calculate and display percentage and score
|
||||
* @param score
|
||||
*/
|
||||
public void setScore(int score) {
|
||||
final int scorePercent = score * MULTIPLIER_TO_GET_PERCENTAGE;
|
||||
binding.resultProgressBar.setProgress(scorePercent);
|
||||
binding.tvResultProgress.setText(score +" / " + NUMBER_OF_QUESTIONS);
|
||||
final String message = getResources().getString(R.string.congratulatory_message_quiz,scorePercent + "%");
|
||||
binding.congratulatoryMessage.setText(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* to go to Contibutions Activity
|
||||
*/
|
||||
public void launchContributionActivity(){
|
||||
startActivityWithFlags(
|
||||
this, MainActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP,
|
||||
Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
startActivityWithFlags(
|
||||
this, MainActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP,
|
||||
Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to call intent to an activity
|
||||
* @param context
|
||||
* @param cls
|
||||
* @param flags
|
||||
* @param <T>
|
||||
*/
|
||||
public static <T> void startActivityWithFlags(Context context, Class<T> cls, int... flags) {
|
||||
Intent intent = new Intent(context, cls);
|
||||
for (int flag: flags) {
|
||||
intent.addFlags(flag);
|
||||
}
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* to inflate menu
|
||||
* @param menu
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.menu_about, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* if share option selected then take screenshot and launch alert
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.share_app_icon) {
|
||||
View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
|
||||
Bitmap screenShot = getScreenShot(rootView);
|
||||
showAlert(screenShot);
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* to store the screenshot of image in bitmap variable temporarily
|
||||
* @param view
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap getScreenShot(View view) {
|
||||
View screenView = view.getRootView();
|
||||
screenView.setDrawingCacheEnabled(true);
|
||||
Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
|
||||
screenView.setDrawingCacheEnabled(false);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* share the screenshot through social media
|
||||
* @param bitmap
|
||||
*/
|
||||
void shareScreen(Bitmap bitmap) {
|
||||
try {
|
||||
File file = new File(this.getExternalCacheDir(),"screen.png");
|
||||
FileOutputStream fOut = new FileOutputStream(file);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
|
||||
fOut.flush();
|
||||
fOut.close();
|
||||
file.setReadable(true, false);
|
||||
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
|
||||
intent.setType("image/png");
|
||||
startActivity(Intent.createChooser(intent, getString(R.string.share_image_via)));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It display the alertDialog with Image of screenshot
|
||||
* @param screenshot
|
||||
*/
|
||||
public void showAlert(Bitmap screenshot) {
|
||||
AlertDialog.Builder alertadd = new AlertDialog.Builder(QuizResultActivity.this);
|
||||
LayoutInflater factory = LayoutInflater.from(QuizResultActivity.this);
|
||||
final View view = factory.inflate(R.layout.image_alert_layout, null);
|
||||
ImageView screenShotImage = view.findViewById(R.id.alert_image);
|
||||
screenShotImage.setImageBitmap(screenshot);
|
||||
TextView shareMessage = view.findViewById(R.id.alert_text);
|
||||
shareMessage.setText(R.string.quiz_result_share_message);
|
||||
alertadd.setView(view);
|
||||
alertadd.setPositiveButton(R.string.about_translate_proceed, (dialog, which) -> shareScreen(screenshot));
|
||||
alertadd.setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.cancel());
|
||||
alertadd.show();
|
||||
}
|
||||
}
|
||||
192
app/src/main/java/fr/free/nrw/commons/quiz/QuizResultActivity.kt
Normal file
192
app/src/main/java/fr/free/nrw/commons/quiz/QuizResultActivity.kt
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
package fr.free.nrw.commons.quiz
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
||||
import fr.free.nrw.commons.databinding.ActivityQuizResultBinding
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.contributions.MainActivity
|
||||
|
||||
|
||||
/**
|
||||
* Displays the final score of quiz and congratulates the user
|
||||
*/
|
||||
class QuizResultActivity : AppCompatActivity() {
|
||||
|
||||
private var binding: ActivityQuizResultBinding? = null
|
||||
private val NUMBER_OF_QUESTIONS = 5
|
||||
private val MULTIPLIER_TO_GET_PERCENTAGE = 20
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityQuizResultBinding.inflate(layoutInflater)
|
||||
setContentView(binding?.root)
|
||||
|
||||
setSupportActionBar(binding?.toolbar?.toolbar)
|
||||
|
||||
binding?.quizResultNext?.setOnClickListener {
|
||||
launchContributionActivity()
|
||||
}
|
||||
|
||||
intent?.extras?.let { extras ->
|
||||
val score = extras.getInt("QuizResult", 0)
|
||||
setScore(score)
|
||||
} ?: run {
|
||||
startActivityWithFlags(
|
||||
this, MainActivity::class.java,
|
||||
Intent.FLAG_ACTIVITY_CLEAR_TOP, Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
)
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
binding = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
/**
|
||||
* To calculate and display percentage and score
|
||||
* @param score
|
||||
*/
|
||||
@SuppressLint("StringFormatInvalid", "SetTextI18n")
|
||||
fun setScore(score: Int) {
|
||||
val scorePercent = score * MULTIPLIER_TO_GET_PERCENTAGE
|
||||
binding?.resultProgressBar?.progress = scorePercent
|
||||
binding?.tvResultProgress?.text = "$score / $NUMBER_OF_QUESTIONS"
|
||||
val message = resources.getString(R.string.congratulatory_message_quiz, "$scorePercent%")
|
||||
binding?.congratulatoryMessage?.text = message
|
||||
}
|
||||
|
||||
/**
|
||||
* To go to Contributions Activity
|
||||
*/
|
||||
fun launchContributionActivity() {
|
||||
startActivityWithFlags(
|
||||
this, MainActivity::class.java,
|
||||
Intent.FLAG_ACTIVITY_CLEAR_TOP, Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
startActivityWithFlags(
|
||||
this, MainActivity::class.java,
|
||||
Intent.FLAG_ACTIVITY_CLEAR_TOP, Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
)
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to call intent to an activity
|
||||
* @param context
|
||||
* @param cls
|
||||
* @param flags
|
||||
*/
|
||||
companion object {
|
||||
fun <T> startActivityWithFlags(context: Context, cls: Class<T>, vararg flags: Int) {
|
||||
val intent = Intent(context, cls)
|
||||
flags.forEach { flag -> intent.addFlags(flag) }
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To inflate menu
|
||||
* @param menu
|
||||
* @return
|
||||
*/
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
menuInflater.inflate(R.menu.menu_about, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* If share option selected then take screenshot and launch alert
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == R.id.share_app_icon) {
|
||||
val rootView = window.decorView.findViewById<View>(android.R.id.content)
|
||||
val screenShot = getScreenShot(rootView)
|
||||
showAlert(screenShot)
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
/**
|
||||
* To store the screenshot of image in bitmap variable temporarily
|
||||
* @param view
|
||||
* @return
|
||||
*/
|
||||
fun getScreenShot(view: View): Bitmap {
|
||||
val screenView = view.rootView
|
||||
screenView.isDrawingCacheEnabled = true
|
||||
val bitmap = Bitmap.createBitmap(screenView.drawingCache)
|
||||
screenView.isDrawingCacheEnabled = false
|
||||
return bitmap
|
||||
}
|
||||
|
||||
/**
|
||||
* Share the screenshot through social media
|
||||
* @param bitmap
|
||||
*/
|
||||
@SuppressLint("SetWorldReadable")
|
||||
fun shareScreen(bitmap: Bitmap) {
|
||||
try {
|
||||
val file = File(this.externalCacheDir, "screen.png")
|
||||
FileOutputStream(file).use { fOut ->
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut)
|
||||
fOut.flush()
|
||||
}
|
||||
file.setReadable(true, false)
|
||||
val intent = Intent(Intent.ACTION_SEND).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file))
|
||||
type = "image/png"
|
||||
}
|
||||
startActivity(Intent.createChooser(intent, getString(R.string.share_image_via)))
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It displays the AlertDialog with Image of screenshot
|
||||
* @param screenshot
|
||||
*/
|
||||
fun showAlert(screenshot: Bitmap) {
|
||||
val alertadd = AlertDialog.Builder(this)
|
||||
val factory = LayoutInflater.from(this)
|
||||
val view = factory.inflate(R.layout.image_alert_layout, null)
|
||||
val screenShotImage = view.findViewById<ImageView>(R.id.alert_image)
|
||||
screenShotImage.setImageBitmap(screenshot)
|
||||
val shareMessage = view.findViewById<TextView>(R.id.alert_text)
|
||||
shareMessage.setText(R.string.quiz_result_share_message)
|
||||
alertadd.setView(view)
|
||||
alertadd.setPositiveButton(R.string.about_translate_proceed) { dialog, _ ->
|
||||
shareScreen(screenshot)
|
||||
}
|
||||
alertadd.setNegativeButton(android.R.string.cancel) { dialog, _ ->
|
||||
dialog.cancel()
|
||||
}
|
||||
alertadd.show()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
package fr.free.nrw.commons.quiz;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Used to group to or more radio buttons to ensure
|
||||
* that at a particular time only one of them is selected
|
||||
*/
|
||||
public class RadioGroupHelper {
|
||||
|
||||
public List<CompoundButton> radioButtons = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor to group radio buttons
|
||||
* @param radios
|
||||
*/
|
||||
public RadioGroupHelper(RadioButton... radios) {
|
||||
super();
|
||||
for (RadioButton rb : radios) {
|
||||
add(rb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to group radio buttons
|
||||
* @param activity
|
||||
* @param radiosIDs
|
||||
*/
|
||||
public RadioGroupHelper(Activity activity, int... radiosIDs) {
|
||||
this(activity.findViewById(android.R.id.content),radiosIDs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to group radio buttons
|
||||
* @param rootView
|
||||
* @param radiosIDs
|
||||
*/
|
||||
public RadioGroupHelper(View rootView, int... radiosIDs) {
|
||||
super();
|
||||
for (int radioButtonID : radiosIDs) {
|
||||
add(rootView.findViewById(radioButtonID));
|
||||
}
|
||||
}
|
||||
|
||||
private void add(CompoundButton button){
|
||||
this.radioButtons.add(button);
|
||||
button.setOnClickListener(onClickListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* listener to ensure only one of the radio button is selected
|
||||
*/
|
||||
View.OnClickListener onClickListener = v -> {
|
||||
for (CompoundButton rb : radioButtons) {
|
||||
if (rb != v) rb.setChecked(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package fr.free.nrw.commons.quiz
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.View
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.RadioButton
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* Used to group to or more radio buttons to ensure
|
||||
* that at a particular time only one of them is selected
|
||||
*/
|
||||
class RadioGroupHelper {
|
||||
|
||||
val radioButtons: MutableList<CompoundButton> = ArrayList()
|
||||
|
||||
/**
|
||||
* Constructor to group radio buttons
|
||||
* @param radios
|
||||
*/
|
||||
constructor(vararg radios: RadioButton) {
|
||||
for (rb in radios) {
|
||||
add(rb)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to group radio buttons
|
||||
* @param activity
|
||||
* @param radiosIDs
|
||||
*/
|
||||
constructor(activity: Activity, vararg radiosIDs: Int) : this(
|
||||
*radiosIDs.map { id -> activity.findViewById<RadioButton>(id) }.toTypedArray()
|
||||
)
|
||||
|
||||
/**
|
||||
* Constructor to group radio buttons
|
||||
* @param rootView
|
||||
* @param radiosIDs
|
||||
*/
|
||||
constructor(rootView: View, vararg radiosIDs: Int) {
|
||||
for (radioButtonID in radiosIDs) {
|
||||
add(rootView.findViewById(radioButtonID))
|
||||
}
|
||||
}
|
||||
|
||||
private fun add(button: CompoundButton) {
|
||||
radioButtons.add(button)
|
||||
button.setOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
/**
|
||||
* listener to ensure only one of the radio button is selected
|
||||
*/
|
||||
private val onClickListener = View.OnClickListener { v ->
|
||||
for (rb in radioButtons) {
|
||||
if (rb != v) rb.isChecked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue