diff --git a/.gitignore b/.gitignore
index 72882161a7..f94cbdc52a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,9 +40,6 @@ proguard
# Log files
*.log
-# Raw folder
-assets
-
# Android Studio Navigation editor temp folder
.navigation
diff --git a/app/build.gradle b/app/build.gradle
index c6f95c554e..2d17cf3c37 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,8 +10,8 @@ android {
applicationId "org.ole.planet.myplanet"
minSdkVersion 26
targetSdkVersion 34
- versionCode 2085
- versionName "0.20.85"
+ versionCode 2086
+ versionName "0.20.86"
ndkVersion '21.3.6528147'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@@ -85,8 +85,8 @@ android {
def planetViPin = project.findProperty('PLANET_VI_PIN') ?: ""
def planetXelaUrl = project.findProperty('PLANET_XELA_URL') ?: ""
def planetXelaPin = project.findProperty('PLANET_XELA_PIN') ?: ""
- //def planetUriurUrl = project.findProperty('PLANET_URIUR_URL') ?: ""
- //def planetUriurPin = project.findProperty('PLANET_URIUR_PIN') ?: ""
+ def planetUriurUrl = project.findProperty('PLANET_URIUR_URL') ?: ""
+ def planetUriurPin = project.findProperty('PLANET_URIUR_PIN') ?: ""
def planetRuiruUrl = project.findProperty('PLANET_RUIRU_URL') ?: ""
def planetRuiruPin = project.findProperty('PLANET_RUIRU_PIN') ?: ""
def planetEmbakasiUrl = project.findProperty('PLANET_EMBAKASI_URL') ?: ""
@@ -114,18 +114,18 @@ android {
it.buildConfigField 'String', 'PLANET_VI_PIN', "\"${planetViPin}\""
it.buildConfigField 'String', 'PLANET_XELA_URL', "\"${planetXelaUrl}\""
it.buildConfigField 'String', 'PLANET_XELA_PIN', "\"${planetXelaPin}\""
- //it.buildConfigField('String', 'PLANET_URIUR_URL', "\"${planetUriurUrl}\"")
- //it.buildConfigField('String', 'PLANET_URIUR_PIN', "\"${planetUriurPin}\"")
- it.buildConfigField('String', 'PLANET_RUIRU_URL', "\"${planetRuiruUrl}\"")
- it.buildConfigField('String', 'PLANET_RUIRU_PIN', "\"${planetRuiruPin}\"")
- it.buildConfigField('String', 'PLANET_EMBAKASI_URL', "\"${planetEmbakasiUrl}\"")
- it.buildConfigField('String', 'PLANET_EMBAKASI_PIN', "\"${planetEmbakasiPin}\"")
- it.buildConfigField('String', 'PLANET_CAMBRIDGE_URL', "\"${planetCambridgeUrl}\"")
- it.buildConfigField('String', 'PLANET_CAMBRIDGE_PIN', "\"${planetCambridgePin}\"")
- //it.buildConfigField('String', 'PLANET_EGDIRBMAC_URL', "\"${planetEgdirbmacUrl}\"")
- //it.buildConfigField('String', 'PLANET_EGDIRBMAC_PIN', "\"${planetEgdirbmacPin}\"")
- it.buildConfigField('String', 'PLANET_PALMBAY_URL', "\"${planetPalmBayUrl}\"")
- it.buildConfigField('String', 'PLANET_PALMBAY_PIN', "\"${planetPalmBayPin}\"")
+ it.buildConfigField 'String', 'PLANET_URIUR_URL', "\"${planetUriurUrl}\""
+ it.buildConfigField 'String', 'PLANET_URIUR_PIN', "\"${planetUriurPin}\""
+ it.buildConfigField 'String', 'PLANET_RUIRU_URL', "\"${planetRuiruUrl}\""
+ it.buildConfigField 'String', 'PLANET_RUIRU_PIN', "\"${planetRuiruPin}\""
+ it.buildConfigField 'String', 'PLANET_EMBAKASI_URL', "\"${planetEmbakasiUrl}\""
+ it.buildConfigField 'String', 'PLANET_EMBAKASI_PIN', "\"${planetEmbakasiPin}\""
+ it.buildConfigField 'String', 'PLANET_CAMBRIDGE_URL', "\"${planetCambridgeUrl}\""
+ it.buildConfigField 'String', 'PLANET_CAMBRIDGE_PIN', "\"${planetCambridgePin}\""
+ //it.buildConfigField 'String', 'PLANET_EGDIRBMAC_URL', "\"${planetEgdirbmacUrl}\""
+ //it.buildConfigField 'String', 'PLANET_EGDIRBMAC_PIN', "\"${planetEgdirbmacPin}\""
+ it.buildConfigField 'String', 'PLANET_PALMBAY_URL', "\"${planetPalmBayUrl}\""
+ it.buildConfigField 'String', 'PLANET_PALMBAY_PIN', "\"${planetPalmBayPin}\""
}
}
diff --git a/app/src/main/assets/images/november_challenge.jpeg b/app/src/main/assets/images/november_challenge.jpeg
new file mode 100644
index 0000000000..885e65f056
Binary files /dev/null and b/app/src/main/assets/images/november_challenge.jpeg differ
diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt
index 24cfe28d1c..83545b2d85 100644
--- a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt
@@ -29,6 +29,8 @@ import org.ole.planet.myplanet.base.PermissionActivity.Companion.hasInstallPermi
import org.ole.planet.myplanet.callback.OnHomeItemClickListener
import org.ole.planet.myplanet.callback.OnRatingChangeListener
import org.ole.planet.myplanet.model.RealmMyLibrary
+import org.ole.planet.myplanet.model.RealmUserChallengeActions
+import org.ole.planet.myplanet.model.RealmUserChallengeActions.Companion.createAction
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.service.UserProfileDbHandler.Companion.KEY_RESOURCE_DOWNLOAD
import org.ole.planet.myplanet.service.UserProfileDbHandler.Companion.KEY_RESOURCE_OPEN
@@ -150,13 +152,29 @@ abstract class BaseContainerFragment : BaseResourceFragment() {
val filenameArray = items.resourceLocalAddress?.split("\\.".toRegex())?.toTypedArray()
val extension = filenameArray?.get(filenameArray.size - 1)
val mimetype = Utilities.getMimeType(items.resourceLocalAddress)
+ val userId = "${model?.id}"
+
+ val existingAction = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", userId)
+ .equalTo("resourceId", items.resourceId)
+ .findFirst()
+
if (mimetype != null) {
if (mimetype.contains("image")) {
openIntent(items, ImageViewerActivity::class.java)
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
} else if (mimetype.contains("pdf")) {
openPdf(items)
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
} else if (mimetype.contains("audio")) {
openIntent(items, AudioPlayerActivity::class.java)
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
} else {
checkMoreFileExtensions(extension, items)
}
@@ -164,14 +182,38 @@ abstract class BaseContainerFragment : BaseResourceFragment() {
}
private fun checkMoreFileExtensions(extension: String?, items: RealmMyLibrary) {
+ val userId = "${model?.id}"
+ val existingAction = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", userId)
+ .equalTo("resourceId", items.resourceId)
+ .findFirst()
+
when (extension) {
- "txt" -> openIntent(items, TextFileViewerActivity::class.java)
- "md" -> openIntent(items, MarkdownViewerActivity::class.java)
- "csv" -> openIntent(items, CSVViewerActivity::class.java)
- "apk" -> installApk(items)
- else -> Toast.makeText(
- activity, getString(R.string.this_file_type_is_currently_unsupported), Toast.LENGTH_LONG
- ).show()
+ "txt" -> {
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
+ openIntent(items, TextFileViewerActivity::class.java)
+ }
+ "md" -> {
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
+ openIntent(items, MarkdownViewerActivity::class.java)
+ }
+ "csv" -> {
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
+ openIntent(items, CSVViewerActivity::class.java)
+ }
+ "apk" -> {
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
+ installApk(items)
+ }
+ else -> Toast.makeText(activity, getString(R.string.this_file_type_is_currently_unsupported), Toast.LENGTH_LONG).show()
}
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt.lite b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt.lite
index 5d5c62b869..8a64f08109 100644
--- a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt.lite
+++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt.lite
@@ -29,6 +29,8 @@ import org.ole.planet.myplanet.R
import org.ole.planet.myplanet.callback.OnHomeItemClickListener
import org.ole.planet.myplanet.callback.OnRatingChangeListener
import org.ole.planet.myplanet.model.RealmMyLibrary
+import org.ole.planet.myplanet.model.RealmUserChallengeActions
+import org.ole.planet.myplanet.model.RealmUserChallengeActions.Companion.createAction
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.service.UserProfileDbHandler.Companion.KEY_RESOURCE_DOWNLOAD
import org.ole.planet.myplanet.service.UserProfileDbHandler.Companion.KEY_RESOURCE_OPEN
@@ -150,13 +152,29 @@ abstract class BaseContainerFragment : BaseResourceFragment() {
val filenameArray = items.resourceLocalAddress?.split("\\.".toRegex())?.toTypedArray()
val extension = filenameArray?.get(filenameArray.size - 1)
val mimetype = Utilities.getMimeType(items.resourceLocalAddress)
+ val userId = "${model?.id}"
+
+ val existingAction = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", userId)
+ .equalTo("resourceId", items.resourceId)
+ .findFirst()
+
if (mimetype != null) {
if (mimetype.contains("image")) {
openIntent(items, ImageViewerActivity::class.java)
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
} else if (mimetype.contains("pdf")) {
openPdf(items)
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
} else if (mimetype.contains("audio")) {
openIntent(items, AudioPlayerActivity::class.java)
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
} else {
checkMoreFileExtensions(extension, items)
}
@@ -164,14 +182,38 @@ abstract class BaseContainerFragment : BaseResourceFragment() {
}
private fun checkMoreFileExtensions(extension: String?, items: RealmMyLibrary) {
+ val userId = "${model?.id}"
+ val existingAction = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", userId)
+ .equalTo("resourceId", items.resourceId)
+ .findFirst()
+
when (extension) {
- "txt" -> openIntent(items, TextFileViewerActivity::class.java)
- "md" -> openIntent(items, MarkdownViewerActivity::class.java)
- "csv" -> openIntent(items, CSVViewerActivity::class.java)
-// "apk" -> installApk(items)
- else -> Toast.makeText(
- activity, getString(R.string.this_file_type_is_currently_unsupported), Toast.LENGTH_LONG
- ).show()
+ "txt" -> {
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
+ openIntent(items, TextFileViewerActivity::class.java)
+ }
+ "md" -> {
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
+ openIntent(items, MarkdownViewerActivity::class.java)
+ }
+ "csv" -> {
+ if (existingAction == null) {
+ createAction(mRealm, userId, items.resourceId, "resourceOpen")
+ }
+ openIntent(items, CSVViewerActivity::class.java)
+ }
+// "apk" -> {
+// if (existingAction == null) {
+// createAction(mRealm, userId, items.resourceId, "resourceOpen")
+// }
+// installApk(items)
+// }
+ else -> Toast.makeText(activity, getString(R.string.this_file_type_is_currently_unsupported), Toast.LENGTH_LONG).show()
}
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmUserChallengeActions.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmUserChallengeActions.kt
new file mode 100644
index 0000000000..7cadbbfc00
--- /dev/null
+++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmUserChallengeActions.kt
@@ -0,0 +1,29 @@
+package org.ole.planet.myplanet.model
+
+import io.realm.Realm
+import io.realm.RealmObject
+import io.realm.annotations.PrimaryKey
+import java.util.UUID
+
+open class RealmUserChallengeActions : RealmObject() {
+ @PrimaryKey
+ var id: String = UUID.randomUUID().toString()
+ var userId: String? = null
+ var actionType: String? = null
+ var resourceId: String? = null
+ var time: Long = 0
+
+ companion object {
+ fun createAction(realm: Realm, userId: String, resourceId: String?, actionType: String) {
+ realm.executeTransaction { transactionRealm ->
+ val action = transactionRealm.createObject(
+ RealmUserChallengeActions::class.java, UUID.randomUUID().toString()
+ )
+ action.userId = userId
+ action.actionType = actionType
+ action.resourceId = resourceId
+ action.time = System.currentTimeMillis()
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt b/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt
index c1cf2115d0..71a46e768f 100644
--- a/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/service/UserProfileDbHandler.kt
@@ -36,15 +36,14 @@ class UserProfileDbHandler(context: Context) {
}
}
- val userModel: RealmUserModel?
- get() {
- if (mRealm.isClosed) {
- mRealm = realmService.realmInstance
- }
- return mRealm.where(RealmUserModel::class.java)
- .equalTo("id", settings.getString("userId", ""))
- .findFirst()
+ val userModel: RealmUserModel? get() {
+ if (mRealm.isClosed) {
+ mRealm = realmService.realmInstance
}
+ return mRealm.where(RealmUserModel::class.java)
+ .equalTo("id", settings.getString("userId", ""))
+ .findFirst()
+ }
fun onLogin() {
if (!mRealm.isInTransaction) {
@@ -89,10 +88,8 @@ class UserProfileDbHandler(context: Context) {
return offlineActivities
}
- val lastVisit: Long?
- get() = mRealm.where(RealmOfflineActivity::class.java).max("loginTime") as Long?
- val offlineVisits: Int
- get() = getOfflineVisits(userModel)
+ val lastVisit: Long? get() = mRealm.where(RealmOfflineActivity::class.java).max("loginTime") as Long?
+ val offlineVisits: Int get() = getOfflineVisits(userModel)
fun getOfflineVisits(m: RealmUserModel?): Int { val dbUsers = mRealm.where(RealmOfflineActivity::class.java).equalTo("userName", m?.name).equalTo("type", KEY_LOGIN).findAll()
return if (!dbUsers.isEmpty()) {
@@ -126,6 +123,7 @@ class UserProfileDbHandler(context: Context) {
if (model?.id?.startsWith("guest") == true) {
return
}
+
if (!mRealm.isInTransaction) mRealm.beginTransaction()
val offlineActivities = mRealm.copyToRealm(createResourceUser(model))
offlineActivities.type = type
@@ -143,33 +141,31 @@ class UserProfileDbHandler(context: Context) {
return offlineActivities
}
- val numberOfResourceOpen: String
- get() {
- val count = mRealm.where(RealmResourceActivity::class.java).equalTo("user", fullName)
- .equalTo("type", KEY_RESOURCE_OPEN).count()
- return if (count == 0L) "" else "Resource opened $count times."
- }
+ val numberOfResourceOpen: String get() {
+ val count = mRealm.where(RealmResourceActivity::class.java).equalTo("user", fullName)
+ .equalTo("type", KEY_RESOURCE_OPEN).count()
+ return if (count == 0L) "" else "Resource opened $count times."
+ }
- val maxOpenedResource: String
- get() {
- val result = mRealm.where(RealmResourceActivity::class.java)
- .equalTo("user", fullName).equalTo("type", KEY_RESOURCE_OPEN)
- .findAll().where().distinct("resourceId").findAll()
- var maxCount = 0L
- var maxOpenedResource = ""
- for (realmResourceActivities in result) {
- val count = mRealm.where(RealmResourceActivity::class.java)
- .equalTo("user", fullName)
- .equalTo("type", KEY_RESOURCE_OPEN)
- .equalTo("resourceId", realmResourceActivities.resourceId).count()
-
- if (count > maxCount) {
- maxCount = count
- maxOpenedResource = "${realmResourceActivities.title}"
- }
+ val maxOpenedResource: String get() {
+ val result = mRealm.where(RealmResourceActivity::class.java)
+ .equalTo("user", fullName).equalTo("type", KEY_RESOURCE_OPEN)
+ .findAll().where().distinct("resourceId").findAll()
+ var maxCount = 0L
+ var maxOpenedResource = ""
+ for (realmResourceActivities in result) {
+ val count = mRealm.where(RealmResourceActivity::class.java)
+ .equalTo("user", fullName)
+ .equalTo("type", KEY_RESOURCE_OPEN)
+ .equalTo("resourceId", realmResourceActivities.resourceId).count()
+
+ if (count > maxCount) {
+ maxCount = count
+ maxOpenedResource = "${realmResourceActivities.title}"
}
- return if (maxCount == 0L) "" else "$maxOpenedResource opened $maxCount times"
}
+ return if (maxCount == 0L) "" else "$maxOpenedResource opened $maxCount times"
+ }
companion object {
const val KEY_LOGIN = "login"
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt
index 98e5ba502d..a1b1696a1b 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatDetailFragment.kt
@@ -15,6 +15,7 @@ import org.ole.planet.myplanet.databinding.FragmentChatDetailBinding
import org.ole.planet.myplanet.datamanager.*
import org.ole.planet.myplanet.model.*
import org.ole.planet.myplanet.model.RealmChatHistory.Companion.addConversationToChatHistory
+import org.ole.planet.myplanet.model.RealmUserChallengeActions.Companion.createAction
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.ui.dashboard.DashboardActivity
import org.ole.planet.myplanet.utilities.Utilities
@@ -341,6 +342,8 @@ class ChatDetailFragment : Fragment() {
}
(requireActivity() as? DashboardActivity)?.refreshChatHistoryList()
}
+
+ createAction(mRealm, "${user?.id}", "${response.body()?.couchDBResponse?.id}", "ai research")
} else {
fragmentChatDetailBinding.textGchatIndicator.visibility = View.VISIBLE
fragmentChatDetailBinding.textGchatIndicator.text = if (response.message() == "null"){
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt
index 776d36ec72..91e0646a3b 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt
@@ -22,6 +22,7 @@ import org.ole.planet.myplanet.model.RealmChatHistory
import org.ole.planet.myplanet.model.RealmMyTeam
import org.ole.planet.myplanet.model.RealmNews
import org.ole.planet.myplanet.model.RealmNews.Companion.createNews
+import org.ole.planet.myplanet.model.RealmUserChallengeActions.Companion.createAction
import org.ole.planet.myplanet.model.RealmUserModel
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.ui.news.ExpandableListAdapter
@@ -213,7 +214,10 @@ class ChatHistoryListAdapter(var context: Context, private var chatHistory: List
map["chat"] = "true"
map["news"] = Gson().toJson(serializedMap)
- createNews(map, mRealm, user, null)
+ val n = user?.let { it1 -> createNews(map, mRealm, it1, null) }
+ if (section== "community") {
+ createAction(mRealm, "${n?.userId}", n?.id, "voice")
+ }
fragment.refreshChatHistoryList()
dialog.dismiss()
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/courses/AdapterMyProgress.kt b/app/src/main/java/org/ole/planet/myplanet/ui/courses/AdapterMyProgress.kt
index bab4c137d1..61c50b93fe 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/courses/AdapterMyProgress.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/courses/AdapterMyProgress.kt
@@ -42,7 +42,7 @@ class AdapterMyProgress(private val context: Context, private val list: JsonArra
val stepMistake = list[position].asJsonObject["stepMistake"].asJsonObject
rowMyProgressBinding.llProgress.removeAllViews()
- if (stepMistake.keySet().size > 0) {
+ if (stepMistake.keySet().isNotEmpty()) {
itemProgressBinding = ItemProgressBinding.inflate(LayoutInflater.from(context))
itemProgressBinding.step.text = HtmlCompat.fromHtml("Step", HtmlCompat.FROM_HTML_MODE_LEGACY)
itemProgressBinding.mistake.text = HtmlCompat.fromHtml("Mistake", HtmlCompat.FROM_HTML_MODE_LEGACY)
@@ -50,8 +50,8 @@ class AdapterMyProgress(private val context: Context, private val list: JsonArra
stepMistake.keySet().forEach {
rowMyProgressBinding.llProgress.removeAllViews()
- itemProgressBinding.step.text = (it.toInt().plus(1).toString())
- itemProgressBinding.mistake.text = stepMistake[it].asInt.toString()
+ itemProgressBinding.step.text = "${it.toInt().plus(1)}"
+ itemProgressBinding.mistake.text = "${stepMistake[it].asInt}"
rowMyProgressBinding.llProgress.addView(itemProgressBinding.root)
}
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CoursesFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CoursesFragment.kt
index 6fd0317f3e..8d0cfebeb0 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/courses/CoursesFragment.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/courses/CoursesFragment.kt
@@ -304,7 +304,7 @@ class CoursesFragment : BaseRecyclerFragment(), OnCourseItemSele
if (userModel?.id?.startsWith("guest") == true) {
DialogUtils.guestDialog(requireContext())
} else {
- redirectToMyCourses();
+ redirectToMyCourses()
}
}
.setNegativeButton(R.string.ok) { dialog: DialogInterface, _: Int ->
@@ -317,7 +317,7 @@ class CoursesFragment : BaseRecyclerFragment(), OnCourseItemSele
}
fun redirectToMyCourses() {
- val fragment = CoursesFragment.newInstance(isMyCourseLib = true)
+ val fragment = newInstance(isMyCourseLib = true)
parentFragmentManager.beginTransaction()
.replace(R.id.fragment_container, fragment)
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/courses/MyProgressFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/courses/MyProgressFragment.kt
index e5fcc403f7..83f0a3c3bd 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/courses/MyProgressFragment.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/courses/MyProgressFragment.kt
@@ -37,58 +37,79 @@ class MyProgressFragment : Fragment() {
private fun initializeData() {
val realm = DatabaseService(requireActivity()).realmInstance
val user = UserProfileDbHandler(requireActivity()).userModel
- val mycourses = RealmMyCourse.getMyCourseByUserId(
- user?.id, realm.where(RealmMyCourse::class.java).findAll()
- )
- val arr = JsonArray()
- val courseProgress = RealmCourseProgress.getCourseProgress(realm, user?.id)
- mycourses.forEach { it ->
- val obj = JsonObject()
- obj.addProperty("courseName", it.courseTitle)
- obj.addProperty("courseId", it.courseId)
- obj.add("progress", courseProgress[it.id])
- val submissions = it.courseId?.let { it1 ->
- realm.where(RealmSubmission::class.java)
- .equalTo("userId", user?.id)
- .contains("parentId", it1)
- .equalTo("type", "exam")
+ val courseData = fetchCourseData(realm, user?.id)
+ fragmentMyProgressBinding.rvMyprogress.layoutManager = LinearLayoutManager(requireActivity())
+ fragmentMyProgressBinding.rvMyprogress.adapter = AdapterMyProgress(requireActivity(), courseData)
+ }
+
+ companion object {
+ fun fetchCourseData(realm: Realm, userId: String?): JsonArray {
+ val mycourses = RealmMyCourse.getMyCourseByUserId(
+ userId,
+ realm.where(RealmMyCourse::class.java).findAll()
+ )
+ val arr = JsonArray()
+ val courseProgress = RealmCourseProgress.getCourseProgress(realm, userId)
+
+ mycourses.forEach { course ->
+ val obj = JsonObject()
+ obj.addProperty("courseName", course.courseTitle)
+ obj.addProperty("courseId", course.courseId)
+ obj.add("progress", courseProgress[course.id])
+
+ val submissions = course.courseId?.let { courseId ->
+ realm.where(RealmSubmission::class.java)
+ .equalTo("userId", userId)
+ .contains("parentId", courseId)
+ .equalTo("type", "exam")
+ .findAll()
+ }
+ val exams = realm.where(RealmStepExam::class.java)
+ .equalTo("courseId", course.courseId)
.findAll()
+ val examIds: List = exams.map { it.id as String }
+
+ if (submissions != null) {
+ submissionMap(submissions, realm, examIds, obj)
+ }
+ arr.add(obj)
}
- val exams = realm.where(RealmStepExam::class.java)
- .equalTo("courseId", it.courseId)
- .findAll()
- val examIds: List = exams.map { it.id as String }
- if (submissions != null) {
- submissionMap(submissions, realm, examIds, obj)
- }
- arr.add(obj)
+ return arr
}
- fragmentMyProgressBinding.rvMyprogress.layoutManager = LinearLayoutManager(requireActivity())
- fragmentMyProgressBinding.rvMyprogress.adapter = AdapterMyProgress(requireActivity(), arr)
- }
- private fun submissionMap(submissions: RealmResults, realm: Realm, examIds: List, obj: JsonObject) {
- var totalMistakes = 0
- submissions.forEach {
- val answers = realm.where(RealmAnswer::class.java)
- .equalTo("submissionId", it.id)
- .findAll()
- val mistakesMap = HashMap()
- answers.forEach { r ->
- val question = realm.where(RealmExamQuestion::class.java)
- .equalTo("id", r.questionId)
- .findFirst()
- if (examIds.contains(question?.examId)) {
- totalMistakes += r.mistakes
- if (mistakesMap.containsKey(question?.examId)) {
- mistakesMap["${examIds.indexOf(question?.examId)}"] = mistakesMap[question?.examId]!!.plus(r.mistakes)
- } else {
- mistakesMap["${examIds.indexOf(question?.examId)}"] = r.mistakes
+ private fun submissionMap(submissions: RealmResults, realm: Realm, examIds: List, obj: JsonObject) {
+ var totalMistakes = 0
+ submissions.forEach {
+ val answers = realm.where(RealmAnswer::class.java)
+ .equalTo("submissionId", it.id)
+ .findAll()
+ val mistakesMap = HashMap()
+ answers.forEach { r ->
+ val question = realm.where(RealmExamQuestion::class.java)
+ .equalTo("id", r.questionId)
+ .findFirst()
+ if (examIds.contains(question?.examId)) {
+ totalMistakes += r.mistakes
+ if (mistakesMap.containsKey(question?.examId)) {
+ mistakesMap["${examIds.indexOf(question?.examId)}"] = mistakesMap[question?.examId]!!.plus(r.mistakes)
+ } else {
+ mistakesMap["${examIds.indexOf(question?.examId)}"] = r.mistakes
+ }
}
}
+ obj.add("stepMistake", Gson().fromJson(Gson().toJson(mistakesMap), JsonObject::class.java))
+ obj.addProperty("mistakes", totalMistakes)
+ }
+ }
+
+ fun getCourseProgress(courseData: JsonArray, courseId: String): JsonObject? {
+ courseData.forEach { element ->
+ val course = element.asJsonObject
+ if (course.get("courseId").asString == courseId) {
+ return course.getAsJsonObject("progress")
+ }
}
- obj.add("stepMistake", Gson().fromJson(Gson().toJson(mistakesMap), JsonObject::class.java))
- obj.addProperty("mistakes", totalMistakes)
+ return null
}
}
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.kt
index b295f33bd1..dbf8d03f87 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.kt
@@ -22,6 +22,7 @@ import androidx.core.content.res.ResourcesCompat
import androidx.core.view.MenuItemCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
+import androidx.lifecycle.lifecycleScope
import com.google.android.material.navigation.NavigationBarView
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
@@ -37,6 +38,9 @@ import io.realm.Case
import io.realm.RealmChangeListener
import io.realm.RealmObject
import io.realm.RealmResults
+import io.realm.Sort
+import kotlinx.coroutines.launch
+import org.ole.planet.myplanet.BuildConfig
import org.ole.planet.myplanet.MainApplication.Companion.context
import org.ole.planet.myplanet.R
import org.ole.planet.myplanet.base.BaseContainerFragment
@@ -44,17 +48,21 @@ import org.ole.planet.myplanet.base.BaseResourceFragment.Companion.getLibraryLis
import org.ole.planet.myplanet.callback.OnHomeItemClickListener
import org.ole.planet.myplanet.databinding.ActivityDashboardBinding
import org.ole.planet.myplanet.databinding.CustomTabBinding
+import org.ole.planet.myplanet.model.RealmMyCourse
import org.ole.planet.myplanet.model.RealmMyLibrary
import org.ole.planet.myplanet.model.RealmNotification
import org.ole.planet.myplanet.model.RealmStepExam
import org.ole.planet.myplanet.model.RealmSubmission
import org.ole.planet.myplanet.model.RealmTeamTask
+import org.ole.planet.myplanet.model.RealmUserChallengeActions
import org.ole.planet.myplanet.model.RealmUserModel
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.ui.SettingActivity
import org.ole.planet.myplanet.ui.chat.ChatHistoryListFragment
import org.ole.planet.myplanet.ui.community.CommunityTabFragment
import org.ole.planet.myplanet.ui.courses.CoursesFragment
+import org.ole.planet.myplanet.ui.courses.MyProgressFragment.Companion.fetchCourseData
+import org.ole.planet.myplanet.ui.courses.MyProgressFragment.Companion.getCourseProgress
import org.ole.planet.myplanet.ui.dashboard.notification.NotificationsFragment
import org.ole.planet.myplanet.ui.dashboard.notification.NotificationListener
import org.ole.planet.myplanet.ui.feedback.FeedbackListFragment
@@ -72,9 +80,11 @@ import org.ole.planet.myplanet.utilities.DialogUtils.guestDialog
import org.ole.planet.myplanet.utilities.FileUtils.totalAvailableMemoryRatio
import org.ole.planet.myplanet.utilities.KeyboardUtils.setupUI
import org.ole.planet.myplanet.utilities.LocaleHelper
+import org.ole.planet.myplanet.utilities.MarkdownDialog
import org.ole.planet.myplanet.utilities.TimeUtils.formatDate
import org.ole.planet.myplanet.utilities.Utilities
import org.ole.planet.myplanet.utilities.Utilities.toast
+import java.time.LocalDate
import java.util.Date
import java.util.UUID
import kotlin.math.ceil
@@ -83,7 +93,7 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
private lateinit var activityDashboardBinding: ActivityDashboardBinding
private var headerResult: AccountHeader? = null
var user: RealmUserModel? = null
- private var result: Drawer? = null
+ var result: Drawer? = null
private var menul: TabLayout.Tab? = null
private var menuh: TabLayout.Tab? = null
private var menuc: TabLayout.Tab? = null
@@ -164,8 +174,10 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
activityDashboardBinding.appBarBell.bellToolbar.visibility = View.VISIBLE
}
activityDashboardBinding.appBarBell.ivSync.setOnClickListener {
- isServerReachable(Utilities.getUrl())
- startUpload("dashboard")
+ lifecycleScope.launch {
+ isServerReachable(Utilities.getUrl())
+ startUpload("dashboard")
+ }
}
activityDashboardBinding.appBarBell.imgLogo.setOnClickListener { result?.openDrawer() }
activityDashboardBinding.appBarBell.bellToolbar.setOnMenuItemClickListener { item ->
@@ -179,8 +191,7 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
}
R.id.menu_goOnline -> wifiStatusSwitch()
R.id.action_sync -> {
- isServerReachable(Utilities.getUrl())
- startUpload("dashboard")
+ logSyncInSharedPrefs()
}
R.id.action_feedback -> {
if (user?.id?.startsWith("guest") == false) {
@@ -230,6 +241,117 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
}
}
})
+
+ val loginCount = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "login")
+ .findAll().count()
+
+ val resourceOpenCount = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "resourceOpen")
+ .findAll().count()
+
+ val syncCount = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "sync")
+ .findAll().count()
+
+ val voiceCount = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "voice")
+ .findAll().count()
+
+ val aiResearchCount = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "ai research")
+ .findAll().count()
+
+ val courseData = fetchCourseData(mRealm, user?.id)
+
+ val courseId = "9517e3b45a5bb63e69bb8f269216974d"
+ val progress = getCourseProgress(courseData, courseId)
+
+ val validUrls = listOf(
+ "https://${BuildConfig.PLANET_GUATEMALA_URL}",
+ "https://${BuildConfig.PLANET_XELA_URL}",
+ "https://${BuildConfig.PLANET_URIUR_URL}",
+ "https://${BuildConfig.PLANET_SANPABLO_URL}",
+ "https://${BuildConfig.PLANET_EMBAKASI_URL}",
+ "https://${BuildConfig.PLANET_VI_URL}"
+ )
+
+ val today = LocalDate.now()
+ if (user?.id?.startsWith("guest") == false) {
+ val endDate = LocalDate.of(today.year, 12, 1)
+ if (today.isBefore(endDate)) {
+ if (settings.getString("serverURL", "") in validUrls) {
+ val course = mRealm.where(RealmMyCourse::class.java)
+ .equalTo("courseId", courseId)
+ .findFirst()
+ val courseName = course?.courseTitle
+
+ if (progress != null) {
+ val max = progress.get("max").asInt
+ val current = progress.get("current").asInt
+ val courseStatus = if (current == max) {
+ "$courseName terminado!"
+ } else {
+ "Ingresa al curso $courseName completalo ($current de $max hecho)"
+ }
+ challengeDialog(voiceCount, courseStatus)
+ } else {
+ challengeDialog(voiceCount, "$courseName no iniciado")
+ }
+ }
+ }
+ }
+ }
+
+ fun challengeDialog(voiceCount: Int, courseStatus: String) {
+ val voiceTaskDone = if (voiceCount >= 1) "✅" else "[ ]"
+ val prereqsMet = courseStatus.contains("terminado", ignoreCase = true) && voiceCount >= 1
+ val syncTaskDone = if (prereqsMet) {
+ val lastPrereqAction = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .`in`("actionType", arrayOf("voice", "courseComplete"))
+ .sort("time", Sort.DESCENDING)
+ .findFirst()
+ ?.time ?: 0
+
+ val hasValidSync = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "sync")
+ .greaterThan("time", lastPrereqAction)
+ .count() > 0
+
+ if (hasValidSync) "✅" else "[ ]"
+ } else "[ ]"
+ val courseTaskDone = if (courseStatus.contains("terminado", ignoreCase = true)) "✅ $courseStatus" else "[ ] $courseStatus"
+
+ val isCompleted = syncTaskDone == "✅" && voiceTaskDone == "✅" && courseTaskDone.startsWith("✅")
+ val hasShownCongrats = settings.getBoolean("has_shown_congrats", false)
+
+ if (isCompleted && hasShownCongrats) return
+
+ if (isCompleted && !hasShownCongrats) {
+ editor.putBoolean("has_shown_congrats", true).apply()
+ val markdownContent = """
+ 
+ ### ¡Felicidades Reto Completado!
+ """.trimIndent()
+ MarkdownDialog.newInstance(markdownContent, courseStatus, voiceCount)
+ .show(supportFragmentManager, "markdown_dialog")
+ } else {
+ val markdownContent = """
+ 
+ ### $courseTaskDone
+ ### $voiceTaskDone Comparte tu opinión en Nuestras Voces.
+ ### $syncTaskDone Recuerda sincronizar la aplicacion movil.
+ """.trimIndent()
+ MarkdownDialog.newInstance(markdownContent, courseStatus, voiceCount)
+ .show(supportFragmentManager, "markdown_dialog")
+ }
}
private fun setupRealmListeners() {
@@ -483,7 +605,7 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
if (user?.rolesList?.isEmpty() == true) {
- menu.findItem(R.id.action_setting).setEnabled(false)
+ menu.findItem(R.id.action_setting).isEnabled = false
}
return super.onPrepareOptionsMenu(menu)
}
@@ -702,7 +824,7 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_bell_dashboard, menu)
- menu.findItem(R.id.menu_goOnline).setVisible(showBetaFeature(Constants.KEY_SYNC, this))
+ menu.findItem(R.id.menu_goOnline).isVisible = showBetaFeature(Constants.KEY_SYNC, this)
return super.onCreateOptionsMenu(menu)
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.kt.lite b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.kt.lite
index 92a586ba7c..853cfda8c6 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.kt.lite
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.kt.lite
@@ -22,6 +22,7 @@ import androidx.core.content.res.ResourcesCompat
import androidx.core.view.MenuItemCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
+import androidx.lifecycle.lifecycleScope
import com.google.android.material.navigation.NavigationBarView
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
@@ -37,6 +38,9 @@ import io.realm.Case
import io.realm.RealmChangeListener
import io.realm.RealmObject
import io.realm.RealmResults
+import io.realm.Sort
+import kotlinx.coroutines.launch
+import org.ole.planet.myplanet.BuildConfig
import org.ole.planet.myplanet.MainApplication.Companion.context
import org.ole.planet.myplanet.R
//import org.ole.planet.myplanet.base.BaseContainerFragment
@@ -44,17 +48,21 @@ import org.ole.planet.myplanet.base.BaseResourceFragment.Companion.getLibraryLis
import org.ole.planet.myplanet.callback.OnHomeItemClickListener
import org.ole.planet.myplanet.databinding.ActivityDashboardBinding
import org.ole.planet.myplanet.databinding.CustomTabBinding
+import org.ole.planet.myplanet.model.RealmMyCourse
import org.ole.planet.myplanet.model.RealmMyLibrary
import org.ole.planet.myplanet.model.RealmNotification
import org.ole.planet.myplanet.model.RealmStepExam
import org.ole.planet.myplanet.model.RealmSubmission
import org.ole.planet.myplanet.model.RealmTeamTask
+import org.ole.planet.myplanet.model.RealmUserChallengeActions
import org.ole.planet.myplanet.model.RealmUserModel
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.ui.SettingActivity
import org.ole.planet.myplanet.ui.chat.ChatHistoryListFragment
import org.ole.planet.myplanet.ui.community.CommunityTabFragment
import org.ole.planet.myplanet.ui.courses.CoursesFragment
+import org.ole.planet.myplanet.ui.courses.MyProgressFragment.Companion.fetchCourseData
+import org.ole.planet.myplanet.ui.courses.MyProgressFragment.Companion.getCourseProgress
import org.ole.planet.myplanet.ui.dashboard.notification.NotificationsFragment
import org.ole.planet.myplanet.ui.dashboard.notification.NotificationListener
import org.ole.planet.myplanet.ui.feedback.FeedbackListFragment
@@ -72,9 +80,11 @@ import org.ole.planet.myplanet.utilities.DialogUtils.guestDialog
import org.ole.planet.myplanet.utilities.FileUtils.totalAvailableMemoryRatio
import org.ole.planet.myplanet.utilities.KeyboardUtils.setupUI
import org.ole.planet.myplanet.utilities.LocaleHelper
+import org.ole.planet.myplanet.utilities.MarkdownDialog
import org.ole.planet.myplanet.utilities.TimeUtils.formatDate
import org.ole.planet.myplanet.utilities.Utilities
import org.ole.planet.myplanet.utilities.Utilities.toast
+import java.time.LocalDate
import java.util.Date
import java.util.UUID
import kotlin.math.ceil
@@ -83,7 +93,7 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
private lateinit var activityDashboardBinding: ActivityDashboardBinding
private var headerResult: AccountHeader? = null
var user: RealmUserModel? = null
- private var result: Drawer? = null
+ var result: Drawer? = null
private var menul: TabLayout.Tab? = null
private var menuh: TabLayout.Tab? = null
private var menuc: TabLayout.Tab? = null
@@ -164,8 +174,10 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
activityDashboardBinding.appBarBell.bellToolbar.visibility = View.VISIBLE
}
activityDashboardBinding.appBarBell.ivSync.setOnClickListener {
- isServerReachable(Utilities.getUrl())
- startUpload("dashboard")
+ lifecycleScope.launch {
+ isServerReachable(Utilities.getUrl())
+ startUpload("dashboard")
+ }
}
activityDashboardBinding.appBarBell.imgLogo.setOnClickListener { result?.openDrawer() }
activityDashboardBinding.appBarBell.bellToolbar.setOnMenuItemClickListener { item ->
@@ -179,8 +191,7 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
}
R.id.menu_goOnline -> wifiStatusSwitch()
R.id.action_sync -> {
- isServerReachable(Utilities.getUrl())
- startUpload("dashboard")
+ logSyncInSharedPrefs()
}
R.id.action_feedback -> {
if (user?.id?.startsWith("guest") == false) {
@@ -230,6 +241,117 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
}
}
})
+
+ val loginCount = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "login")
+ .findAll().count()
+
+ val resourceOpenCount = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "resourceOpen")
+ .findAll().count()
+
+ val syncCount = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "sync")
+ .findAll().count()
+
+ val voiceCount = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "voice")
+ .findAll().count()
+
+ val aiResearchCount = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "ai research")
+ .findAll().count()
+
+ val courseData = fetchCourseData(mRealm, user?.id)
+
+ val courseId = "9517e3b45a5bb63e69bb8f269216974d"
+ val progress = getCourseProgress(courseData, courseId)
+
+ val validUrls = listOf(
+ "https://${BuildConfig.PLANET_GUATEMALA_URL}",
+ "https://${BuildConfig.PLANET_XELA_URL}",
+ "https://${BuildConfig.PLANET_URIUR_URL}",
+ "https://${BuildConfig.PLANET_SANPABLO_URL}",
+ "https://${BuildConfig.PLANET_EMBAKASI_URL}",
+ "https://${BuildConfig.PLANET_VI_URL}"
+ )
+
+ val today = LocalDate.now()
+ if (user?.id?.startsWith("guest") == false) {
+ val endDate = LocalDate.of(today.year, 12, 1)
+ if (today.isBefore(endDate)) {
+ if (settings.getString("serverURL", "") in validUrls) {
+ val course = mRealm.where(RealmMyCourse::class.java)
+ .equalTo("courseId", courseId)
+ .findFirst()
+ val courseName = course?.courseTitle
+
+ if (progress != null) {
+ val max = progress.get("max").asInt
+ val current = progress.get("current").asInt
+ val courseStatus = if (current == max) {
+ "$courseName terminado!"
+ } else {
+ "Ingresa al curso $courseName completalo ($current de $max hecho)"
+ }
+ challengeDialog(voiceCount, courseStatus)
+ } else {
+ challengeDialog(voiceCount, "$courseName no iniciado")
+ }
+ }
+ }
+ }
+ }
+
+ fun challengeDialog(voiceCount: Int, courseStatus: String) {
+ val voiceTaskDone = if (voiceCount >= 1) "✅" else "[ ]"
+ val prereqsMet = courseStatus.contains("terminado", ignoreCase = true) && voiceCount >= 1
+ val syncTaskDone = if (prereqsMet) {
+ val lastPrereqAction = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .`in`("actionType", arrayOf("voice", "courseComplete"))
+ .sort("time", Sort.DESCENDING)
+ .findFirst()
+ ?.time ?: 0
+
+ val hasValidSync = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", user?.id)
+ .equalTo("actionType", "sync")
+ .greaterThan("time", lastPrereqAction)
+ .count() > 0
+
+ if (hasValidSync) "✅" else "[ ]"
+ } else "[ ]"
+ val courseTaskDone = if (courseStatus.contains("terminado", ignoreCase = true)) "✅ $courseStatus" else "[ ] $courseStatus"
+
+ val isCompleted = syncTaskDone == "✅" && voiceTaskDone == "✅" && courseTaskDone.startsWith("✅")
+ val hasShownCongrats = settings.getBoolean("has_shown_congrats", false)
+
+ if (isCompleted && hasShownCongrats) return
+
+ if (isCompleted && !hasShownCongrats) {
+ editor.putBoolean("has_shown_congrats", true).apply()
+ val markdownContent = """
+ 
+ ### ¡Felicidades Reto Completado!
+ """.trimIndent()
+ MarkdownDialog.newInstance(markdownContent, courseStatus, voiceCount)
+ .show(supportFragmentManager, "markdown_dialog")
+ } else {
+ val markdownContent = """
+ 
+ ### $courseTaskDone
+ ### $voiceTaskDone Comparte tu opinión en Nuestras Voces.
+ ### $syncTaskDone Recuerda sincronizar la aplicacion movil.
+ """.trimIndent()
+ MarkdownDialog.newInstance(markdownContent, courseStatus, voiceCount)
+ .show(supportFragmentManager, "markdown_dialog")
+ }
}
private fun setupRealmListeners() {
@@ -483,7 +605,7 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
if (user?.rolesList?.isEmpty() == true) {
- menu.findItem(R.id.action_setting).setEnabled(false)
+ menu.findItem(R.id.action_setting).isEnabled = false
}
return super.onPrepareOptionsMenu(menu)
}
@@ -702,7 +824,7 @@ class DashboardActivity : DashboardElementActivity(), OnHomeItemClickListener, N
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_bell_dashboard, menu)
- menu.findItem(R.id.menu_goOnline).setVisible(showBetaFeature(Constants.KEY_SYNC, this))
+ menu.findItem(R.id.menu_goOnline).isVisible = showBetaFeature(Constants.KEY_SYNC, this)
return super.onCreateOptionsMenu(menu)
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsFragment.kt
index c85b04d3be..51e4bb5567 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsFragment.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/news/NewsFragment.kt
@@ -1,13 +1,11 @@
package org.ole.planet.myplanet.ui.news
import android.content.res.Configuration
-import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver
import com.google.gson.Gson
import com.google.gson.JsonArray
@@ -21,6 +19,7 @@ import org.ole.planet.myplanet.datamanager.DatabaseService
import org.ole.planet.myplanet.model.RealmMyLibrary
import org.ole.planet.myplanet.model.RealmNews
import org.ole.planet.myplanet.model.RealmNews.Companion.createNews
+import org.ole.planet.myplanet.model.RealmUserChallengeActions.Companion.createAction
import org.ole.planet.myplanet.model.RealmUserModel
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.ui.chat.ChatDetailFragment
@@ -30,7 +29,6 @@ import org.ole.planet.myplanet.utilities.FileUtils.openOleFolder
import org.ole.planet.myplanet.utilities.JsonUtils.getString
import org.ole.planet.myplanet.utilities.KeyboardUtils.setupUI
-@RequiresApi(api = Build.VERSION_CODES.O)
class NewsFragment : BaseNewsFragment() {
private lateinit var fragmentNewsBinding: FragmentNewsBinding
var user: RealmUserModel? = null
@@ -122,6 +120,8 @@ class NewsFragment : BaseNewsFragment() {
llImage?.removeAllViews()
adapterNews?.addItem(n)
setData(newsList)
+
+ createAction(mRealm, "${user?.id}", "${n?.id}", "voice")
}
fragmentNewsBinding.addNewsImage.setOnClickListener {
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/sync/DashboardElementActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/sync/DashboardElementActivity.kt
index c111550f16..f4e213c23d 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/sync/DashboardElementActivity.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/sync/DashboardElementActivity.kt
@@ -17,6 +17,7 @@ import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
+import androidx.lifecycle.lifecycleScope
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.google.android.material.bottomnavigation.BottomNavigationView
import kotlinx.coroutines.CoroutineScope
@@ -24,6 +25,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.ole.planet.myplanet.R
import org.ole.planet.myplanet.callback.OnRatingChangeListener
+import org.ole.planet.myplanet.model.RealmUserChallengeActions.Companion.createAction
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.ui.SettingActivity
import org.ole.planet.myplanet.ui.community.CommunityTabFragment
@@ -112,13 +114,21 @@ abstract class DashboardElementActivity : SyncActivity(), FragmentManager.OnBack
startActivity(Intent(this, SettingActivity::class.java))
}
R.id.action_sync -> {
- isServerReachable(Utilities.getUrl())
- startUpload("dashboard")
+ logSyncInSharedPrefs()
}
}
return super.onOptionsItemSelected(item)
}
+ fun logSyncInSharedPrefs() {
+ lifecycleScope.launch {
+ if (isServerReachable(Utilities.getUrl())) {
+ startUpload("dashboard")
+ createAction(mRealm, "${profileDbHandler.userModel?.id}", null, "sync")
+ }
+ }
+ }
+
@SuppressLint("RestrictedApi")
fun wifiStatusSwitch() {
val resIcon = ContextCompat.getDrawable(this, R.drawable.goonline)
@@ -128,7 +138,7 @@ abstract class DashboardElementActivity : SyncActivity(), FragmentManager.OnBack
val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
startActivity(intent)
if (mWifi?.isConnected == true) {
- wifi.setWifiEnabled(false)
+ wifi.isWifiEnabled = false
if (resIcon != null) {
DrawableCompat.setTintMode(resIcon.mutate(), PorterDuff.Mode.SRC_ATOP)
DrawableCompat.setTint(resIcon, ContextCompat.getColor(this, R.color.green))
@@ -136,7 +146,7 @@ abstract class DashboardElementActivity : SyncActivity(), FragmentManager.OnBack
goOnline.icon = resIcon
Toast.makeText(this, getString(R.string.wifi_is_turned_off_saving_battery_power), Toast.LENGTH_LONG).show()
} else {
- wifi.setWifiEnabled(true)
+ wifi.isWifiEnabled = true
Toast.makeText(this, getString(R.string.turning_on_wifi_please_wait), Toast.LENGTH_LONG).show()
Handler(Looper.getMainLooper()).postDelayed({ connectToWifi() }, 5000)
if (resIcon != null) {
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/sync/LoginActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/sync/LoginActivity.kt
index 7a0aca264f..1432276248 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/sync/LoginActivity.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/sync/LoginActivity.kt
@@ -131,9 +131,9 @@ class LoginActivity : SyncActivity(), TeamListAdapter.OnItemClickListener {
submitForm(activityLoginBinding.inputName.text.toString(), activityLoginBinding.inputPassword.text.toString())
} else {
val builder = AlertDialog.Builder(this)
- builder.setMessage("member " + activityLoginBinding.inputName.text.toString() + " is archived")
+ builder.setMessage("member ${activityLoginBinding.inputName.text} is archived")
builder.setCancelable(false)
- builder.setPositiveButton("Ok") { dialog: DialogInterface, _: Int ->
+ builder.setPositiveButton("ok") { dialog: DialogInterface, _: Int ->
dialog.dismiss()
activityLoginBinding.inputName.setText(R.string.empty_text)
activityLoginBinding.inputPassword.setText(R.string.empty_text)
diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/sync/SyncActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/sync/SyncActivity.kt
index f7265cda84..d8f7eace03 100644
--- a/app/src/main/java/org/ole/planet/myplanet/ui/sync/SyncActivity.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/ui/sync/SyncActivity.kt
@@ -6,12 +6,14 @@ import android.graphics.drawable.AnimationDrawable
import android.os.Build
import android.os.Bundle
import android.text.*
+import android.util.Log
import android.view.*
import android.webkit.URLUtil
import android.widget.*
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.SwitchCompat
+import androidx.lifecycle.lifecycleScope
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager
@@ -37,6 +39,7 @@ import org.ole.planet.myplanet.datamanager.*
import org.ole.planet.myplanet.datamanager.ApiClient.client
import org.ole.planet.myplanet.datamanager.Service.*
import org.ole.planet.myplanet.model.*
+import org.ole.planet.myplanet.model.RealmUserChallengeActions.Companion.createAction
import org.ole.planet.myplanet.service.*
import org.ole.planet.myplanet.ui.dashboard.DashboardActivity
import org.ole.planet.myplanet.ui.team.AdapterTeam.OnUserSelectedListener
@@ -70,7 +73,7 @@ abstract class SyncActivity : ProcessUserDataActivity(), SyncListener, CheckVers
private lateinit var syncSwitch: SwitchCompat
private var connectionResult = false
lateinit var mRealm: Realm
- private lateinit var editor: SharedPreferences.Editor
+ lateinit var editor: SharedPreferences.Editor
private var syncTimeInterval = intArrayOf(60 * 60, 3 * 60 * 60)
lateinit var syncIcon: ImageView
lateinit var syncIconDrawable: AnimationDrawable
@@ -187,44 +190,98 @@ abstract class SyncActivity : ProcessUserDataActivity(), SyncListener, CheckVers
}
@Throws(Exception::class)
- fun isServerReachable(processedUrl: String?): Boolean {
- customProgressDialog?.setText(getString(R.string.connecting_to_server))
- customProgressDialog?.show()
- val apiInterface = client?.create(ApiInterface::class.java)
- apiInterface?.isPlanetAvailable("$processedUrl/_all_dbs")?.enqueue(object : Callback {
- override fun onResponse(call: Call, response: Response) {
- try {
- customProgressDialog?.dismiss()
- val ss = response.body()?.string()
- val myList = ss?.split(",".toRegex())?.dropLastWhile { it.isEmpty() }?.let { listOf(*it.toTypedArray()) }
+// fun isServerReachable(processedUrl: String?): Boolean {
+// customProgressDialog?.setText(getString(R.string.connecting_to_server))
+// customProgressDialog?.show()
+// val apiInterface = client?.create(ApiInterface::class.java)
+// apiInterface?.isPlanetAvailable("$processedUrl/_all_dbs")?.enqueue(object : Callback {
+// override fun onResponse(call: Call, response: Response) {
+// try {
+// customProgressDialog?.dismiss()
+// val ss = response.body()?.string()
+// val myList = ss?.split(",".toRegex())?.dropLastWhile { it.isEmpty() }?.let { listOf(*it.toTypedArray()) }
+// if ((myList?.size ?: 0) < 8) {
+// alertDialogOkay(getString(R.string.check_the_server_address_again_what_i_connected_to_wasn_t_the_planet_server))
+// } else {
+// startSync()
+// }
+// } catch (e: Exception) {
+// e.printStackTrace()
+// syncFailed = true
+// if (extractProtocol("$processedUrl") == context.getString(R.string.http_protocol)) {
+// alertDialogOkay(getString(R.string.device_couldn_t_reach_local_server))
+// } else if (extractProtocol("$processedUrl") == context.getString(R.string.https_protocol)) {
+// alertDialogOkay(getString(R.string.device_couldn_t_reach_nation_server))
+// }
+// customProgressDialog?.dismiss()
+// }
+// }
+//
+// override fun onFailure(call: Call, t: Throwable) {
+// syncFailed = true
+// if (extractProtocol("$processedUrl") == context.getString(R.string.http_protocol)) {
+// alertDialogOkay(getString(R.string.device_couldn_t_reach_local_server))
+// } else if (extractProtocol("$processedUrl") == context.getString(R.string.https_protocol)) {
+// alertDialogOkay(getString(R.string.device_couldn_t_reach_nation_server))
+// }
+// customProgressDialog?.dismiss()
+// }
+// })
+// return connectionResult
+// }
+
+ suspend fun isServerReachable(processedUrl: String?): Boolean = withContext(Dispatchers.IO) {
+ try {
+ withContext(Dispatchers.Main) {
+ customProgressDialog?.setText(getString(R.string.connecting_to_server))
+ customProgressDialog?.show()
+ }
+
+ val apiInterface = client?.create(ApiInterface::class.java)
+ val response = apiInterface?.isPlanetAvailable("$processedUrl/_all_dbs")?.execute()
+
+ response?.let {
+ if (it.isSuccessful) {
+ val myList = it.body()?.string()?.split(",")?.dropLastWhile { it.isEmpty() }
if ((myList?.size ?: 0) < 8) {
- alertDialogOkay(getString(R.string.check_the_server_address_again_what_i_connected_to_wasn_t_the_planet_server))
+ withContext(Dispatchers.Main) {
+ alertDialogOkay(getString(R.string.check_the_server_address_again_what_i_connected_to_wasn_t_the_planet_server))
+ }
+ false
} else {
- startSync()
- }
- } catch (e: Exception) {
- e.printStackTrace()
- syncFailed = true
- if (extractProtocol("$processedUrl") == context.getString(R.string.http_protocol)) {
- alertDialogOkay(getString(R.string.device_couldn_t_reach_local_server))
- } else if (extractProtocol("$processedUrl") == context.getString(R.string.https_protocol)) {
- alertDialogOkay(getString(R.string.device_couldn_t_reach_nation_server))
+ withContext(Dispatchers.Main) {
+ startSync()
+ }
+ true
}
- customProgressDialog?.dismiss()
+ } else {
+ handleServerError()
+ false
}
+ } ?: run {
+ handleServerError()
+ false
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ handleServerError()
+ false
+ } finally {
+ withContext(Dispatchers.Main) {
+ customProgressDialog?.dismiss()
}
+ }
+ }
- override fun onFailure(call: Call, t: Throwable) {
- syncFailed = true
- if (extractProtocol("$processedUrl") == context.getString(R.string.http_protocol)) {
- alertDialogOkay(getString(R.string.device_couldn_t_reach_local_server))
- } else if (extractProtocol("$processedUrl") == context.getString(R.string.https_protocol)) {
- alertDialogOkay(getString(R.string.device_couldn_t_reach_nation_server))
- }
- customProgressDialog?.dismiss()
- }
- })
- return connectionResult
+ private suspend fun handleServerError() {
+ withContext(Dispatchers.Main) {
+ syncFailed = true
+ if (extractProtocol(processedUrl) == getString(R.string.http_protocol)) {
+ alertDialogOkay(getString(R.string.device_couldn_t_reach_local_server))
+ } else if (extractProtocol(processedUrl) == getString(R.string.https_protocol)) {
+ alertDialogOkay(getString(R.string.device_couldn_t_reach_nation_server))
+ }
+ }
}
private fun dateCheck(dialog: MaterialDialog) {
@@ -397,11 +454,7 @@ abstract class SyncActivity : ProcessUserDataActivity(), SyncListener, CheckVers
val daysDiff = TimeUnit.MILLISECONDS.toDays(msDiff)
return if (daysDiff >= maxDays) {
val alertDialogBuilder = AlertDialog.Builder(this, R.style.AlertDialogTheme)
- alertDialogBuilder.setMessage(
- getString(R.string.it_has_been_more_than) + (daysDiff - 1) + getString(
- R.string.days_since_you_last_synced_this_device
- ) + getString(R.string.connect_it_to_the_server_over_wifi_and_sync_it_to_reactivate_this_tablet)
- )
+ alertDialogBuilder.setMessage("${getString(R.string.it_has_been_more_than)}${(daysDiff - 1)}${getString(R.string.days_since_you_last_synced_this_device)}${getString(R.string.connect_it_to_the_server_over_wifi_and_sync_it_to_reactivate_this_tablet)}")
alertDialogBuilder.setPositiveButton(R.string.okay) { _: DialogInterface?, _: Int ->
Toast.makeText(applicationContext, getString(R.string.connect_to_the_server_over_wifi_and_sync_your_device_to_continue), Toast.LENGTH_LONG).show()
}
@@ -414,6 +467,25 @@ abstract class SyncActivity : ProcessUserDataActivity(), SyncListener, CheckVers
fun onLogin() {
val handler = UserProfileDbHandler(this)
+
+ val userId = handler.userModel?.id
+ if (userId != null && userId.startsWith("guest") == false) {
+ Log.d("okuro", "called")
+ val latestAction = mRealm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", userId).sort("time", Sort.DESCENDING).findFirst()
+
+ val currentTime = System.currentTimeMillis()
+ val thresholdTime = 24 * 60 * 60 * 1000
+
+ if (latestAction == null) {
+ createAction(mRealm, userId, null, "login")
+ } else {
+ if (currentTime - latestAction.time >= thresholdTime) {
+ createAction(mRealm, userId, null, "login")
+ }
+ }
+ }
+
handler.onLogin()
handler.onDestroy()
editor.putBoolean(Constants.KEY_LOGIN, true).commit()
@@ -590,7 +662,7 @@ abstract class SyncActivity : ProcessUserDataActivity(), SyncListener, CheckVers
editor.putString("serverProtocol", protocol).apply()
if (serverCheck) {
performSync(dialog)
- } }, { _, _ ->
+ }}, { _, _ ->
clearDataDialog(getString(R.string.you_want_to_connect_to_a_different_server), false) {
serverAddressAdapter?.revertSelection()
}
@@ -797,11 +869,13 @@ abstract class SyncActivity : ProcessUserDataActivity(), SyncListener, CheckVers
private fun continueSyncProcess() {
try {
- if (isSync) {
- isServerReachable(processedUrl)
- } else if (forceSync) {
- isServerReachable(processedUrl)
- startUpload("login")
+ lifecycleScope.launch {
+ if (isSync) {
+ isServerReachable(processedUrl)
+ } else if (forceSync) {
+ isServerReachable(processedUrl)
+ startUpload("login")
+ }
}
} catch (e: Exception) {
e.printStackTrace()
diff --git a/app/src/main/java/org/ole/planet/myplanet/utilities/Markdown.kt b/app/src/main/java/org/ole/planet/myplanet/utilities/Markdown.kt
index ff9e1a60d9..d250657cb9 100644
--- a/app/src/main/java/org/ole/planet/myplanet/utilities/Markdown.kt
+++ b/app/src/main/java/org/ole/planet/myplanet/utilities/Markdown.kt
@@ -48,7 +48,7 @@ object Markdown {
.usePlugin(object : AbstractMarkwonPlugin() {
override fun configure(registry: MarkwonPlugin.Registry) {
registry.require(ImagesPlugin::class.java) { imagesPlugin ->
- imagesPlugin.addSchemeHandler(FileSchemeHandler.create())
+ imagesPlugin.addSchemeHandler(FileSchemeHandler.createWithAssets(context.assets))
imagesPlugin.addSchemeHandler(NetworkSchemeHandler.create())
imagesPlugin.addSchemeHandler(OkHttpNetworkSchemeHandler.create())
}
diff --git a/app/src/main/java/org/ole/planet/myplanet/utilities/MarkdownDialog.kt b/app/src/main/java/org/ole/planet/myplanet/utilities/MarkdownDialog.kt
new file mode 100644
index 0000000000..b10b87fc9b
--- /dev/null
+++ b/app/src/main/java/org/ole/planet/myplanet/utilities/MarkdownDialog.kt
@@ -0,0 +1,157 @@
+package org.ole.planet.myplanet.utilities
+
+import android.os.Bundle
+import android.text.Spannable
+import android.text.method.LinkMovementMethod
+import android.text.style.URLSpan
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.DialogFragment
+import com.mikepenz.materialdrawer.Drawer
+import io.realm.Sort
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import org.ole.planet.myplanet.R
+import org.ole.planet.myplanet.callback.OnHomeItemClickListener
+import org.ole.planet.myplanet.databinding.DialogCampaignChallengeBinding
+import org.ole.planet.myplanet.model.RealmUserChallengeActions
+import org.ole.planet.myplanet.ui.community.CommunityTabFragment
+import org.ole.planet.myplanet.ui.courses.TakeCourseFragment
+import org.ole.planet.myplanet.ui.dashboard.DashboardActivity
+import org.ole.planet.myplanet.ui.sync.DashboardElementActivity
+import org.ole.planet.myplanet.utilities.Markdown.setMarkdownText
+
+class MarkdownDialog : DialogFragment() {
+ private lateinit var dialogCampaignChallengeBinding: DialogCampaignChallengeBinding
+ private var markdownContent: String = ""
+ private var courseStatus: String = ""
+ private var voiceCount: Int = 0
+
+ companion object {
+ private const val ARG_MARKDOWN_CONTENT = "markdown_content"
+ private const val ARG_COURSE_STATUS = "course_status"
+ private const val ARG_VOICE_COUNT = "voice_count"
+
+ fun newInstance(markdownContent: String, courseStatus: String, voiceCount: Int): MarkdownDialog {
+ val fragment = MarkdownDialog()
+ val args = Bundle().apply {
+ putString(ARG_MARKDOWN_CONTENT, markdownContent)
+ putString(ARG_COURSE_STATUS, courseStatus)
+ putInt(ARG_VOICE_COUNT, voiceCount)
+ }
+ fragment.arguments = args
+ return fragment
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ markdownContent = arguments?.getString(ARG_MARKDOWN_CONTENT) ?: ""
+ courseStatus = arguments?.getString(ARG_COURSE_STATUS) ?: ""
+ voiceCount = arguments?.getInt(ARG_VOICE_COUNT, 0) ?: 0
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+ dialogCampaignChallengeBinding = DialogCampaignChallengeBinding.inflate(inflater, container, false)
+ return dialogCampaignChallengeBinding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ setupMarkdown()
+ setupCourseButton((activity as DashboardActivity).result)
+ dialogCampaignChallengeBinding.markdownTextView.movementMethod = LinkMovementMethod.getInstance()
+ val textWithSpans = dialogCampaignChallengeBinding.markdownTextView.text
+ if (textWithSpans is Spannable) {
+ val urlSpans = textWithSpans.getSpans(0, textWithSpans.length, URLSpan::class.java)
+ for (urlSpan in urlSpans) {
+ val start = textWithSpans.getSpanStart(urlSpan)
+ val end = textWithSpans.getSpanEnd(urlSpan)
+ val dynamicTitle = textWithSpans.subSequence(start, end).toString()
+ textWithSpans.setSpan(CustomClickableSpan(urlSpan.url, dynamicTitle, requireActivity()), start, end, textWithSpans.getSpanFlags(urlSpan))
+ textWithSpans.removeSpan(urlSpan)
+ }
+ }
+ setupCloseButton()
+ }
+
+ override fun onStart() {
+ super.onStart()
+ val dialog = dialog ?: return
+
+ dialog.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ }
+
+ private fun setupMarkdown() {
+ setMarkdownText(dialogCampaignChallengeBinding.markdownTextView, markdownContent)
+ }
+
+ private fun setupCourseButton(drawer: Drawer?) {
+ dialogCampaignChallengeBinding.btnStart.apply {
+ val isCompleted = courseStatus.contains("terminado") &&
+ voiceCount >= 1 &&
+ (activity as? DashboardActivity)?.mRealm?.let { realm ->
+ val lastPrereqAction = realm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", (activity as? DashboardActivity)?.user?.id)
+ .`in`("actionType", arrayOf("voice", "courseComplete"))
+ .sort("time", Sort.DESCENDING)
+ .findFirst()
+ ?.time ?: 0
+
+ realm.where(RealmUserChallengeActions::class.java)
+ .equalTo("userId", (activity as? DashboardActivity)?.user?.id)
+ .equalTo("actionType", "sync")
+ .greaterThan("time", lastPrereqAction)
+ .count() > 0
+ } == true
+
+ visibility = if (isCompleted) View.GONE else View.VISIBLE
+
+ val buttonText = when {
+ courseStatus.contains("no iniciado") -> context.getString(R.string.start)
+ courseStatus.contains("terminado") && voiceCount < 1 -> context.getString(R.string.next)
+ courseStatus.contains("terminado") && voiceCount >= 1 -> context.getString(R.string.sync)
+ else -> context.getString(R.string.continuation)
+ }
+
+ text = buttonText
+ setOnClickListener {
+ val courseId = "9517e3b45a5bb63e69bb8f269216974d"
+ when (buttonText) {
+ context.getString(R.string.start), context.getString(R.string.continuation) -> {
+ val fragment = TakeCourseFragment().apply {
+ arguments = Bundle().apply {
+ putString("id", courseId)
+ }
+ }
+ (activity as? OnHomeItemClickListener)?.openCallFragment(fragment)
+ }
+ context.getString(R.string.next) -> {
+ (activity as DashboardActivity).openCallFragment(CommunityTabFragment())
+ }
+ context.getString(R.string.sync) -> {
+ CoroutineScope(Dispatchers.IO).launch {
+// withContext(Dispatchers.Main) {
+ (activity as DashboardElementActivity).logSyncInSharedPrefs()
+// }
+ }
+ }
+ }
+ if (drawer != null && drawer.isDrawerOpen) {
+ drawer.closeDrawer()
+ }
+ dismiss()
+ }
+ }
+ }
+
+ private fun setupCloseButton() {
+ dialogCampaignChallengeBinding.closeButton.setOnClickListener {
+ dismiss()
+ }
+ }
+}
diff --git a/app/src/main/res/drawable/baseline_close_24.xml b/app/src/main/res/drawable/baseline_close_24.xml
new file mode 100644
index 0000000000..56940e6fb8
--- /dev/null
+++ b/app/src/main/res/drawable/baseline_close_24.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_campaign_challenge.xml b/app/src/main/res/layout/dialog_campaign_challenge.xml
new file mode 100644
index 0000000000..8dbd4a7e1a
--- /dev/null
+++ b/app/src/main/res/layout/dialog_campaign_challenge.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index c52cbbe996..4255e61eaa 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -1198,6 +1198,8 @@
عدد الموارد المفتوحة :
عدد الزيارات
يرجى إدخال رسالة الرد
+ ابدأ
+ استمر
يرجى إكمال الاستبيان لإنهاء الدورة
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 9bce13a3eb..10ab059bc5 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -1198,6 +1198,8 @@
Número de Recursos Abiertos :
Número de Visitas
Por favor, ingrese el mensaje de respuesta
+ iniciar
+ continuar
por favor complete la encuesta para terminar el curso
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 80384d6665..aedd7ae30c 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -1198,6 +1198,8 @@
Nombre de Ressources Ouvertes :
Nombre de Visites
Veuillez entrer le message de réponse
+ démarrer
+ continuer
veuillez compléter le sondage pour terminer le cours
diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml
index 51165db643..817fd9b87d 100644
--- a/app/src/main/res/values-ne/strings.xml
+++ b/app/src/main/res/values-ne/strings.xml
@@ -1198,6 +1198,8 @@
खोलिएका स्रोतहरूको संख्या :
भ्रमणहरूको संख्या
कृपया प्रतिक्रिया सन्देश प्रवेश गर्नुहोस्
+ सुरु गर्नुहोस्
+ जारी राख्नुहोस्
कृपया कोर्स समाप्त गर्न सर्वेक्षण पूरा गर्नुहोस्
diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml
index 861fd52ff5..c3dd039e5e 100644
--- a/app/src/main/res/values-so/strings.xml
+++ b/app/src/main/res/values-so/strings.xml
@@ -1198,6 +1198,8 @@
Tirada Kheyraadka La Furay :
Tirada Booqashooyinka
Fadlan geli farriinta jawaabta
+ bilow
+ sii wad
fadlan dhameystir sahanka si aad u dhameystirto koorsada
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6c272ce887..5e87de0dce 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -600,7 +600,7 @@
Send Survey to:
Send Survey
Previous
- Next
+ next
Submit Answer
All Task
My task
@@ -674,7 +674,7 @@
Feature not available for guest user
Feature Not Available
Health record not available, Sync health data?
- Sync
+ sync
GOT IT
Please make sure your device is horizontal
Click on the logo to get the full menu of your planet: Home, myLibrary, myCourses, Library, Courses, Community, Enterprises, and Surveys
@@ -1198,6 +1198,8 @@
Number of Resources Opened :
Number of Visits
Kindly enter reply message
+ start
+ continue
please complete the survey to finish the course
diff --git a/gradle.properties b/gradle.properties
index 9b2141e1e2..39f4d0c687 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -37,8 +37,8 @@ PLANET_VI_URL=planet.vi.ole.org
PLANET_VI_PIN=0660
PLANET_XELA_URL=10.82.1.150
PLANET_XELA_PIN=4324
-#PLANET_URIUR_URL=planet.uriur.ole.org
-#PLANET_URIUR_PIN=4025
+PLANET_URIUR_URL=planet.uriur.ole.org
+PLANET_URIUR_PIN=4025
PLANET_RUIRU_URL=192.168.100.178
PLANET_RUIRU_PIN=8925
PLANET_EMBAKASI_URL=planet.embakasi.ole.org