Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4159 migrate help fragment to compose #4217

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SOUMEN-PAL Why are we adding both the bom and the normal version of dependencies? We should only add and manage the dependencies. See how we done in https://github.com/kiwix/kiwix-android/pull/4253/files#diff-df8b4af8cccf28e19228317a74d3fba23fed6c067665f72670b7d4986515ad39.

"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")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase on the main branch, there we have added the support for compose in a proper way.

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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we have added androidx.compose.ui:ui-android:1.7.7 in our project. Due to this, we are facing a PrivateResouce lint issue for our close_drawer string. Can you please fix that? IMO add this in in lintConfig file since our app can have the same resource name, and we are getting this name from our R package so it will not conflict with compose internal string.

<issue id="PrivateResource" severity="warning" />

image

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)
}
75 changes: 0 additions & 75 deletions core/src/main/java/org/kiwix/kiwixmobile/core/help/HelpAdapter.kt

This file was deleted.

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is abstract so why we are not implementing it in CustomHelpFragment like we are doing it in KiwixHelpFragment? It will not allow us to build the Custom module without implementing this in CustomHelpFragment.


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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the already defined navController in CoreMainActivity. Like:

val navController = (requireActivity() as CoreMainActivity).navController

After using this, you don't need to define this:

protected abstract val navHostFragmentId: Int

So remove this from HelpFragment as well as from the child fragments.

// 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) }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these fragmentToolbar and fragmentTitle, as well as the onViewCreated method as they are unused now.


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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After moving HelpScreen to compose our HelpAdapter is unused so we should remove the unused code.

// 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