Show changelog in settings
parent
8f8abcc3f6
commit
c458f1eafb
@ -0,0 +1,74 @@
|
|||||||
|
package org.koitharu.kotatsu.settings.about.changelog
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import io.noties.markwon.Markwon
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
|
import kotlinx.coroutines.flow.flowOn
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.exceptions.resolve.DialogErrorObserver
|
||||||
|
import org.koitharu.kotatsu.core.ui.BaseFragment
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.consumeAll
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.container
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.end
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.observe
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.showOrHide
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.start
|
||||||
|
import org.koitharu.kotatsu.databinding.FragmentChangelogBinding
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class ChangelogFragment : BaseFragment<FragmentChangelogBinding>() {
|
||||||
|
|
||||||
|
private val viewModel: ChangelogViewModel by viewModels()
|
||||||
|
|
||||||
|
override fun onCreateViewBinding(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?
|
||||||
|
) = FragmentChangelogBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
|
override fun onViewBindingCreated(binding: FragmentChangelogBinding, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewBindingCreated(binding, savedInstanceState)
|
||||||
|
val markwon = Markwon.create(binding.root.context)
|
||||||
|
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||||
|
binding.progressBar.showOrHide(it)
|
||||||
|
}
|
||||||
|
viewModel.onError.observeEvent(viewLifecycleOwner, DialogErrorObserver(binding.root, this))
|
||||||
|
viewModel.changelog.filterNotNull()
|
||||||
|
.map { markwon.toMarkdown(it) }
|
||||||
|
.flowOn(Dispatchers.Default)
|
||||||
|
.observe(viewLifecycleOwner) {
|
||||||
|
markwon.setParsedMarkdown(binding.textViewContent, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
activity?.setTitle(R.string.changelog)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onApplyWindowInsets(
|
||||||
|
v: View,
|
||||||
|
insets: WindowInsetsCompat
|
||||||
|
): WindowInsetsCompat {
|
||||||
|
val typeMask = WindowInsetsCompat.Type.systemBars()
|
||||||
|
val barsInsets = insets.getInsets(typeMask)
|
||||||
|
val isTablet = !resources.getBoolean(R.bool.is_tablet)
|
||||||
|
val isMaster = container?.id == R.id.container_master
|
||||||
|
val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding)
|
||||||
|
requireViewBinding().textViewContent.setPaddingRelative(
|
||||||
|
basePadding + if (isTablet && !isMaster) 0 else barsInsets.start(v),
|
||||||
|
basePadding,
|
||||||
|
basePadding + if (isTablet && isMaster) 0 else barsInsets.end(v),
|
||||||
|
basePadding + barsInsets.bottom,
|
||||||
|
)
|
||||||
|
return insets.consumeAll(typeMask)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package org.koitharu.kotatsu.settings.about.changelog
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import org.jsoup.internal.StringUtil
|
||||||
|
import org.koitharu.kotatsu.core.github.AppUpdateRepository
|
||||||
|
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class ChangelogViewModel @Inject constructor(
|
||||||
|
private val appUpdateRepository: AppUpdateRepository,
|
||||||
|
) : BaseViewModel() {
|
||||||
|
|
||||||
|
val changelog = MutableStateFlow<String?>(null)
|
||||||
|
|
||||||
|
init {
|
||||||
|
launchLoadingJob(Dispatchers.Default) {
|
||||||
|
val versions = appUpdateRepository.getAvailableVersions()
|
||||||
|
val stringJoiner = StringUtil.StringJoiner("\n\n\n")
|
||||||
|
for (version in versions) {
|
||||||
|
stringJoiner.add("# ")
|
||||||
|
.append(version.name)
|
||||||
|
.append("\n\n")
|
||||||
|
.append(version.description)
|
||||||
|
}
|
||||||
|
changelog.value = stringJoiner.complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/scrollView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
|
||||||
|
android:id="@+id/textView_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="@dimen/screen_padding"
|
||||||
|
android:textAppearance="?textAppearanceBodyMedium"
|
||||||
|
android:textIsSelectable="true"
|
||||||
|
tools:text="@tools:sample/lorem/random" />
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="top"
|
||||||
|
android:indeterminate="true"
|
||||||
|
app:hideAnimationBehavior="escape" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
Loading…
Reference in New Issue