Skip to content

Commit

Permalink
#4159 migrated Help Fragment to jetpack Compose
Browse files Browse the repository at this point in the history
  • Loading branch information
SOUMEN-PAL authored and MohitMaliDeveloper committed Feb 18, 2025
1 parent 102162f commit 6873bd5
Show file tree
Hide file tree
Showing 8 changed files with 427 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.help.HelpFragment

class KiwixHelpFragment : HelpFragment() {
override val navHostFragmentId: Int
get() = org.kiwix.kiwixmobile.R.id.nav_host_fragment

override fun rawTitleDescriptionMap() =
if (sharedPreferenceUtil.isPlayStoreBuildWithAndroid11OrAbove()) {
listOf(
Expand Down
40 changes: 40 additions & 0 deletions buildSrc/src/main/kotlin/Libs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -366,4 +366,44 @@ object Libs {
*/
const val fetch: String = "com.github.tonyofrancis.Fetch:fetch2:" + Versions.fetch
const val fetchOkhttp: String = "com.github.tonyofrancis.Fetch:fetch2okhttp:" + Versions.fetch

/**
* https://developer.android.com/reference/kotlin/androidx/compose/material3
*/
const val androidx_compose_material3: String =
"androidx.compose.material3:material3-android:" + Versions.androidx_compose_material3_version

/**
* https://developer.android.com/reference/kotlin/androidx/activity/compose
*/
const val androidx_activity_compose: String =
"androidx.activity:activity-compose:" + Versions.androidx_activity_compose_version

/**
* https://developer.android.com/develop/ui/compose/documentation
*/
const val androidx_compose_ui: String =
"androidx.compose.ui:ui:" + Versions.androidx_compose_ui_version

const val androidx_compose_bom: String =
"androidx.compose:compose-bom:" + Versions.androidx_compose_bom_version

const val androidx_compose_tooling_preview: String =
"androidx.compose.ui:ui-tooling-preview"

const val androidx_compose_runtime_livedata: String =
"androidx.compose.runtime:runtime-livedata"

const val androidx_compose_runtime_rxjava2: String =
"androidx.compose.runtime:runtime-rxjava2"

/**
* testing libraries for compose
*/
const val androidx_compose_ui_test_junit4: String =
"androidx.compose.ui:ui-test-junit4"

const val androidx_compose_ui_tooling: String =
"androidx.compose.ui:ui-tooling"

}
12 changes: 12 additions & 0 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ object Versions {
const val keeper = "0.16.1"

const val fetch: String = "3.4.1"

const val org_jetbrains_kotlin_plugin_compose = "2.1.10"

const val kotlin_compiler_extension_version = "1.5.15"

const val androidx_compose_material3_version = "1.3.1"

const val androidx_activity_compose_version = "1.10.0"

const val androidx_compose_ui_version = "1.7.7"

const val androidx_compose_bom_version = "2025.01.01"
}

/**
Expand Down
21 changes: 21 additions & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ buildscript {
}
plugins {
`android-library`
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.compose") version Versions.org_jetbrains_kotlin_plugin_compose
}
plugins.apply(KiwixConfigurationPlugin::class)
apply(plugin = "io.objectbox")
Expand All @@ -26,6 +28,12 @@ android {
isMinifyEnabled = false
}
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = Versions.kotlin_compiler_extension_version
}
}

fun shouldUseLocalVersion() = File(projectDir, "libs").exists()
Expand Down Expand Up @@ -63,4 +71,17 @@ dependencies {
implementation(Libs.kotlinx_coroutines_android)
implementation(Libs.kotlinx_coroutines_rx3)
implementation(Libs.zxing)

implementation(Libs.androidx_compose_material3)
implementation(Libs.androidx_activity_compose)

implementation(Libs.androidx_compose_ui)
implementation(platform(Libs.androidx_compose_bom))
implementation(Libs.androidx_compose_ui_tooling)
implementation(Libs.androidx_compose_runtime_livedata)
implementation(Libs.androidx_compose_runtime_rxjava2)

// For Compose UI Testing
androidTestImplementation(Libs.androidx_compose_ui_test_junit4)
debugImplementation(Libs.androidx_compose_ui_tooling)
}
96 changes: 52 additions & 44 deletions core/src/main/java/org/kiwix/kiwixmobile/core/help/HelpFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,83 +17,91 @@
*/
package org.kiwix.kiwixmobile.core.help

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.compose.ui.platform.ComposeView
import androidx.navigation.Navigation
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.base.BaseActivity
import org.kiwix.kiwixmobile.core.base.BaseFragment
import org.kiwix.kiwixmobile.core.databinding.FragmentHelpBinding
import org.kiwix.kiwixmobile.core.error.DiagnosticReportActivity
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import javax.inject.Inject

@Suppress("UnnecessaryAbstractClass")
abstract class HelpFragment : BaseFragment() {

@Inject
lateinit var sharedPreferenceUtil: SharedPreferenceUtil
private var fragmentHelpBinding: FragmentHelpBinding? = null
protected open fun rawTitleDescriptionMap(): List<Pair<Int, Any>> = emptyList()
override val fragmentToolbar: Toolbar? by lazy {
fragmentHelpBinding?.root?.findViewById(R.id.toolbar)
}
override val fragmentTitle: String? by lazy { getString(R.string.menu_help) }

private val titleDescriptionMap by lazy {
rawTitleDescriptionMap().associate { (title, description) ->
val descriptionValue = when (description) {
is String -> description
is Int -> resources.getStringArray(description).joinToString(separator = "\n")
else -> {
throw IllegalArgumentException("Invalid description resource type for title: $title")
}
}
protected abstract val navHostFragmentId: Int

getString(title) to descriptionValue
// Instead of keeping the XML binding, we now directly return a ComposeView.
protected open fun createFragmentView(
inflater: LayoutInflater,
container: ViewGroup?
): View {
return ComposeView(requireContext()).apply {
setContent {
// Create the helpScreen data using your rawTitleDescriptionMap.
val helpScreenData = transformToHelpScreenData(
requireContext(),
rawTitleDescriptionMap()
)
// Retrieve the NavController if your composable needs it.
val navController = Navigation.findNavController(requireActivity(), navHostFragmentId)
// Call your HelpScreen composable.
HelpScreen(data = helpScreenData, navController = navController)
}
}
}

// Each subclass is responsible for providing its own raw data.
protected open fun rawTitleDescriptionMap(): List<Pair<Int, Any>> = emptyList()

// The following properties are now optional – if no longer use an XML toolbar or title,
// we can remove or update these accordingly.
override val fragmentToolbar: Toolbar? by lazy {
// Already Applied ad TopAppBAr in scaffold in composable
null
}
override val fragmentTitle: String? by lazy { getString(R.string.menu_help) }

override fun inject(baseActivity: BaseActivity) {
(baseActivity as CoreMainActivity).cachedComponent.inject(this)
}

// Remove or adjust onViewCreated if you no longer need to manipulate XML-based views.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val activity = requireActivity() as AppCompatActivity
fragmentHelpBinding?.activityHelpDiagnosticImageView?.setOnClickListener {
sendDiagnosticReport()
}
fragmentHelpBinding?.activityHelpDiagnosticTextView?.setOnClickListener {
sendDiagnosticReport()
}
fragmentHelpBinding?.activityHelpRecyclerView?.addItemDecoration(
DividerItemDecoration(activity, DividerItemDecoration.VERTICAL)
)
fragmentHelpBinding?.activityHelpRecyclerView?.adapter = HelpAdapter(titleDescriptionMap)
// Any additional logic that is independent of the XML layout can be kept here.
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
fragmentHelpBinding =
FragmentHelpBinding.inflate(inflater, container, false)
return fragmentHelpBinding?.root
}

private fun sendDiagnosticReport() {
requireActivity().start<DiagnosticReportActivity>()
}
): View? = createFragmentView(inflater, container)
}

override fun onDestroyView() {
super.onDestroyView()
fragmentHelpBinding = null
// Util function to modify the data accordingly
fun transformToHelpScreenData(
context: Context,
rawTitleDescriptionMap: List<Pair<Int, Any>>
): List<HelpScreenItemDataClass> {
return rawTitleDescriptionMap.map { (titleResId, description) ->
val title = context.getString(titleResId)
val descriptionValue = when (description) {
is String -> description
is Int -> context.resources.getStringArray(description).joinToString(separator = "\n")
else -> {
throw IllegalArgumentException("Invalid description resource type for title: $titleResId")
}
}
HelpScreenItemDataClass(title, descriptionValue)
}
}
Loading

0 comments on commit 6873bd5

Please sign in to comment.