Skip to content

Commit d40d3de

Browse files
committed
refactor: modernize ChangelogFragment using Jetpack Compose
1 parent 60df048 commit d40d3de

File tree

1 file changed

+23
-86
lines changed

1 file changed

+23
-86
lines changed

legacy/ui/legacy/src/main/java/com/fsck/k9/ui/changelog/ChangelogFragment.kt

Lines changed: 23 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@ import android.os.Bundle
44
import android.view.LayoutInflater
55
import android.view.View
66
import android.view.ViewGroup
7+
import androidx.compose.ui.platform.ComposeView
8+
import androidx.compose.ui.platform.ViewCompositionStrategy
79
import androidx.fragment.app.Fragment
8-
import androidx.recyclerview.widget.RecyclerView
9-
import androidx.recyclerview.widget.RecyclerView.ViewHolder
1010
import app.k9mail.core.android.common.compat.BundleCompat
11-
import com.fsck.k9.ui.R
12-
import com.fsck.k9.ui.base.loader.observeLoading
13-
import com.google.android.material.checkbox.MaterialCheckBox
14-
import com.google.android.material.textview.MaterialTextView
15-
import de.cketti.changelog.ReleaseItem
11+
import kotlin.getValue
12+
import net.thunderbird.core.ui.contract.mvi.observe
13+
import net.thunderbird.core.ui.theme.api.FeatureThemeProvider
14+
import org.koin.android.ext.android.inject
1615
import org.koin.androidx.viewmodel.ext.android.viewModel
1716
import org.koin.core.parameter.parametersOf
1817

1918
/**
2019
* Displays the changelog entries in a scrolling list
2120
*/
2221
class ChangelogFragment : Fragment() {
22+
private val themeProvider: FeatureThemeProvider by inject()
2323
private val viewModel: ChangelogViewModel by viewModel {
2424
val mode = arguments?.let {
2525
BundleCompat.getSerializable(it, ARG_MODE, ChangeLogMode::class.java)
@@ -28,90 +28,27 @@ class ChangelogFragment : Fragment() {
2828
}
2929

3030
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
31-
return inflater.inflate(R.layout.fragment_changelog, container, false)
32-
}
33-
34-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
35-
val listView = view.findViewById<RecyclerView>(R.id.changelog_list)
36-
37-
viewModel.changelogState.observeLoading(
38-
owner = viewLifecycleOwner,
39-
loadingView = view.findViewById(R.id.changelog_loading),
40-
errorView = view.findViewById(R.id.changelog_error),
41-
dataView = listView,
42-
) { changeLog ->
43-
listView.adapter = ChangelogAdapter(changeLog)
44-
}
45-
46-
setUpShowRecentChangesCheckbox(view)
47-
}
48-
49-
private fun setUpShowRecentChangesCheckbox(view: View) {
50-
val showRecentChangesCheckBox = view.findViewById<MaterialCheckBox>(R.id.show_recent_changes_checkbox)
51-
var isInitialValue = true
52-
viewModel.showRecentChangesState.observe(viewLifecycleOwner) { showRecentChanges ->
53-
showRecentChangesCheckBox.isChecked = showRecentChanges
54-
if (isInitialValue) {
55-
// Don't animate when setting initial value
56-
showRecentChangesCheckBox.jumpDrawablesToCurrentState()
57-
isInitialValue = false
31+
return ComposeView(requireContext()).apply {
32+
setViewCompositionStrategy(
33+
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed,
34+
)
35+
36+
setContent {
37+
val (state, dispatch) = viewModel.observe {}
38+
themeProvider.WithTheme {
39+
ChangelogScreen(
40+
releaseItems = state.value.releaseItems,
41+
showRecentChanges = state.value.showRecentChanges,
42+
onShowRecentChangesCheck = {
43+
dispatch(ChangelogContract.Event.OnShowRecentChangesCheck(state.value.showRecentChanges))
44+
},
45+
)
46+
}
5847
}
5948
}
60-
showRecentChangesCheckBox.setOnCheckedChangeListener { _, isChecked ->
61-
viewModel.setShowRecentChanges(isChecked)
62-
}
6349
}
6450

6551
companion object {
6652
const val ARG_MODE = "mode"
6753
}
6854
}
69-
70-
class ChangelogAdapter(releaseItems: List<ReleaseItem>) : RecyclerView.Adapter<ViewHolder>() {
71-
private val items = releaseItems.flatMap { listOf(it) + it.changes }
72-
73-
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
74-
val layoutInflater = LayoutInflater.from(parent.context)
75-
val view = layoutInflater.inflate(viewType, parent, false)
76-
return when (viewType) {
77-
R.layout.changelog_list_release_item -> ReleaseItemViewHolder(view)
78-
R.layout.changelog_list_change_item -> ChangeItemViewHolder(view)
79-
else -> error("Unsupported view type: $viewType")
80-
}
81-
}
82-
83-
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
84-
when (val item = items[position]) {
85-
is ReleaseItem -> {
86-
val viewHolder = holder as ReleaseItemViewHolder
87-
val context = viewHolder.versionName.context
88-
viewHolder.versionName.text = context.getString(R.string.changelog_version_title, item.versionName)
89-
viewHolder.versionDate.text = item.date
90-
}
91-
92-
is String -> {
93-
val viewHolder = holder as ChangeItemViewHolder
94-
viewHolder.changeText.text = item
95-
}
96-
}
97-
}
98-
99-
override fun getItemViewType(position: Int): Int {
100-
return when (items[position]) {
101-
is ReleaseItem -> R.layout.changelog_list_release_item
102-
is String -> R.layout.changelog_list_change_item
103-
else -> error("Unsupported item type: ${items[position]}")
104-
}
105-
}
106-
107-
override fun getItemCount(): Int = items.size
108-
}
109-
110-
class ReleaseItemViewHolder(view: View) : ViewHolder(view) {
111-
val versionName: MaterialTextView = view.findViewById(R.id.version_name)
112-
val versionDate: MaterialTextView = view.findViewById(R.id.version_date)
113-
}
114-
115-
class ChangeItemViewHolder(view: View) : ViewHolder(view) {
116-
val changeText: MaterialTextView = view.findViewById(R.id.change_text)
117-
}

0 commit comments

Comments
 (0)