Skip to content

Commit 88dedd3

Browse files
frettclaude
andcommitted
Migrate CategoriesFragment from DataBinding/RecyclerView to Compose
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e91de5a commit 88dedd3

5 files changed

Lines changed: 77 additions & 129 deletions

File tree

ui/article-renderer/build.gradle.kts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ android {
1313

1414
buildFeatures {
1515
dataBinding = true
16-
viewBinding = true
1716
}
1817
}
1918

@@ -25,20 +24,16 @@ dependencies {
2524
implementation(libs.androidx.compose.material3)
2625
implementation(libs.androidx.fragment.ktx)
2726
implementation(libs.androidx.lifecycle.livedata.ktx)
28-
implementation(libs.androidx.constraintlayout)
29-
implementation(libs.androidx.recyclerview)
3027

3128
implementation(libs.gtoSupport.androidx.fragment)
3229
implementation(libs.gtoSupport.androidx.lifecycle)
33-
implementation(libs.gtoSupport.androidx.recyclerview)
3430
implementation(libs.gtoSupport.core)
3531
implementation(libs.gtoSupport.kotlin.coroutines)
36-
implementation(libs.gtoSupport.picasso)
3732
implementation(libs.gtoSupport.sync)
38-
implementation(libs.gtoSupport.util)
3933

4034
implementation(libs.colormath.jetpack.compose)
4135
implementation(libs.dagger)
36+
implementation(libs.godtoolsShared.renderer)
4237
implementation(libs.hilt)
4338
implementation(libs.splitties.fragmentargs)
4439

ui/article-renderer/src/main/kotlin/org/cru/godtools/article/ui/categories/CategoriesAdapter.kt

Lines changed: 0 additions & 50 deletions
This file was deleted.

ui/article-renderer/src/main/kotlin/org/cru/godtools/article/ui/categories/CategoriesFragment.kt

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,108 @@ package org.cru.godtools.article.ui.categories
33
import android.os.Bundle
44
import android.view.LayoutInflater
55
import android.view.ViewGroup
6-
import androidx.lifecycle.map
6+
import androidx.compose.foundation.clickable
7+
import androidx.compose.foundation.layout.Arrangement
8+
import androidx.compose.foundation.layout.fillMaxSize
9+
import androidx.compose.foundation.lazy.LazyColumn
10+
import androidx.compose.foundation.lazy.items
11+
import androidx.compose.runtime.Composable
12+
import androidx.compose.runtime.collectAsState
13+
import androidx.compose.runtime.derivedStateOf
14+
import androidx.compose.runtime.getValue
15+
import androidx.compose.runtime.remember
16+
import androidx.compose.ui.Modifier
17+
import androidx.compose.ui.platform.ComposeView
18+
import androidx.compose.ui.platform.ViewCompositionStrategy
19+
import androidx.compose.ui.unit.dp
20+
import androidx.fragment.app.Fragment
21+
import androidx.fragment.app.viewModels
722
import dagger.hilt.android.AndroidEntryPoint
823
import java.util.Locale
924
import javax.inject.Inject
25+
import javax.inject.Named
26+
import okio.FileSystem
1027
import org.ccci.gto.android.common.androidx.fragment.app.findListener
11-
import org.ccci.gto.android.common.androidx.recyclerview.decorator.MarginItemDecoration
28+
import org.cru.godtools.base.tool.BaseToolRendererModule.Companion.TOOL_RESOURCE_FILE_SYSTEM
1229
import org.cru.godtools.base.tool.analytics.model.SCREEN_CATEGORIES
1330
import org.cru.godtools.base.tool.analytics.model.ToolAnalyticsScreenEvent
14-
import org.cru.godtools.base.tool.fragment.BaseToolFragment
31+
import org.cru.godtools.base.tool.viewmodel.LatestPublishedManifestDataModel
32+
import org.cru.godtools.base.ui.theme.GodToolsTheme
33+
import org.cru.godtools.shared.renderer.article.RenderArticleCategory
34+
import org.cru.godtools.shared.renderer.util.ProvideRendererServices
1535
import org.cru.godtools.shared.tool.parser.model.Category
16-
import org.cru.godtools.tool.article.R
17-
import org.cru.godtools.tool.article.databinding.ArticleCategoriesFragmentBinding
1836
import org.greenrobot.eventbus.EventBus
37+
import splitties.fragmentargs.arg
1938

2039
@AndroidEntryPoint
21-
class CategoriesFragment :
22-
BaseToolFragment<ArticleCategoriesFragmentBinding>,
23-
CategorySelectedListener {
24-
constructor() : super(R.layout.article_categories_fragment)
25-
constructor(code: String, locale: Locale) : super(R.layout.article_categories_fragment, code, locale)
40+
class CategoriesFragment() : Fragment() {
41+
constructor(code: String, locale: Locale) : this() {
42+
tool = code
43+
this.locale = locale
44+
}
45+
46+
private var tool by arg<String>()
47+
private var locale by arg<Locale>()
2648

2749
@Inject
2850
internal lateinit var eventBus: EventBus
2951

52+
@Inject
53+
@Named(TOOL_RESOURCE_FILE_SYSTEM)
54+
internal lateinit var resourceFileSystem: FileSystem
55+
3056
// region Lifecycle
31-
override fun onCreateBinding(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
32-
ArticleCategoriesFragmentBinding.inflate(inflater, container, false).apply { setupCategoriesView() }
57+
override fun onCreate(savedInstanceState: Bundle?) {
58+
super.onCreate(savedInstanceState)
59+
setupDataModel()
60+
}
61+
62+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
63+
ComposeView(requireContext()).apply {
64+
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
65+
setContent {
66+
GodToolsTheme {
67+
ProvideRendererServices(resourceFileSystem) {
68+
CategoriesContent()
69+
}
70+
}
71+
}
72+
}
3373

3474
override fun onResume() {
3575
super.onResume()
3676
eventBus.post(ToolAnalyticsScreenEvent(SCREEN_CATEGORIES, tool, locale))
3777
}
3878

39-
override fun onCategorySelected(category: Category?) {
79+
private fun onCategorySelected(category: Category?) {
4080
findListener<CategorySelectedListener>()?.onCategorySelected(category)
4181
}
4282
// endregion Lifecycle
4383

44-
// region Categories View
45-
private fun ArticleCategoriesFragmentBinding.setupCategoriesView() {
46-
categories.apply {
47-
setHasFixedSize(true)
48-
addItemDecoration(
49-
MarginItemDecoration(bottomMargin = resources.getDimensionPixelSize(R.dimen.categories_list_gap))
50-
)
51-
adapter = CategoriesAdapter(viewLifecycleOwner).apply {
52-
callbacks.set(this@CategoriesFragment)
53-
toolDataModel.manifest.map { it?.categories }.observe(viewLifecycleOwner, this)
84+
// region Data Model
85+
private val toolDataModel: LatestPublishedManifestDataModel by viewModels()
86+
87+
private fun setupDataModel() {
88+
toolDataModel.toolCode.value = tool
89+
toolDataModel.locale.value = locale
90+
}
91+
// endregion Data Model
92+
93+
@Composable
94+
private fun CategoriesContent(modifier: Modifier = Modifier) {
95+
val manifest by toolDataModel.manifestFlow.collectAsState(null)
96+
val categories by remember { derivedStateOf { manifest?.categories.orEmpty() } }
97+
98+
LazyColumn(
99+
verticalArrangement = Arrangement.spacedBy(1.dp),
100+
modifier = modifier.fillMaxSize(),
101+
) {
102+
items(categories, key = { it.id ?: it }) { category ->
103+
RenderArticleCategory(
104+
category,
105+
modifier = Modifier.clickable { onCategorySelected(category) }
106+
)
54107
}
55108
}
56109
}
57-
// endregion Categories View
58110
}

ui/article-renderer/src/main/res/layout/article_categories_fragment.xml

Lines changed: 0 additions & 7 deletions
This file was deleted.

ui/article-renderer/src/main/res/layout/list_item_category.xml

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)