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 = """ + ![issues challenge](file:///android_asset/images/november_challenge.jpeg)
+ ### ¡Felicidades Reto Completado! + """.trimIndent() + MarkdownDialog.newInstance(markdownContent, courseStatus, voiceCount) + .show(supportFragmentManager, "markdown_dialog") + } else { + val markdownContent = """ + ![issues challenge](file:///android_asset/images/november_challenge.jpeg)
+ ### $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 = """ + ![issues challenge](file:///android_asset/images/november_challenge.jpeg)
+ ### ¡Felicidades Reto Completado! + """.trimIndent() + MarkdownDialog.newInstance(markdownContent, courseStatus, voiceCount) + .show(supportFragmentManager, "markdown_dialog") + } else { + val markdownContent = """ + ![issues challenge](file:///android_asset/images/november_challenge.jpeg)
+ ### $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 @@ + + + + + + + +