app: setup pagination and a viewmodel for posts

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2020-09-23 22:06:56 +05:30
parent 5260f454ef
commit e1c9b34bbe
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
4 changed files with 58 additions and 20 deletions

View file

@ -50,11 +50,13 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
dependencies {
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_dagger_version"
kapt "androidx.hilt:hilt-compiler:$hilt_androidx_version"
implementation(project(":data"))
implementation(project(":lobsters-api"))
implementation(project(":model"))
implementation 'androidx.core:core-ktx:1.5.0-alpha03'
implementation 'androidx.activity:activity-ktx:1.2.0-alpha08'
implementation 'androidx.appcompat:appcompat:1.3.0-alpha02'
implementation "androidx.compose.foundation:foundation:$compose_version"
implementation "androidx.compose.foundation:foundation-layout:$compose_version"
@ -66,12 +68,14 @@ dependencies {
implementation "androidx.compose.ui:ui-text:$compose_version"
implementation "androidx.compose.ui:ui-text-android:$compose_version"
implementation "androidx.compose.ui:ui-unit:$compose_version"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:$hilt_androidx_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.ui:ui-tooling:$compose_version"
implementation 'com.google.android.material:material:1.3.0-alpha02'
implementation "com.google.dagger:hilt-android:$hilt_version"
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
implementation "com.google.dagger:hilt-android:$hilt_dagger_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_dagger_version"
testImplementation 'junit:junit:4.13'
androidTestImplementation "androidx.ui:ui-test:$compose_version"
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.0.10"

View file

@ -1,47 +1,42 @@
package dev.msfjarvis.lobsters
import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.Text
import androidx.compose.foundation.lazy.LazyColumnFor
import androidx.compose.foundation.lazy.LazyColumnForIndexed
import androidx.compose.material.Scaffold
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Providers
import androidx.compose.runtime.ambientOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.platform.setContent
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import dev.msfjarvis.lobsters.api.LobstersApi
import dev.msfjarvis.lobsters.model.LobstersPost
import dev.msfjarvis.lobsters.data.LobstersViewModel
import dev.msfjarvis.lobsters.ui.LobstersItem
import dev.msfjarvis.lobsters.ui.LobstersTheme
import dev.msfjarvis.lobsters.urllauncher.UrlLauncher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.coroutines.ExperimentalCoroutinesApi
import javax.inject.Inject
val UrlLauncherAmbient = ambientOf<UrlLauncher> { error("Needs to be provided") }
@AndroidEntryPoint
@ExperimentalCoroutinesApi
class MainActivity : AppCompatActivity() {
@Inject lateinit var urlLauncher: UrlLauncher
@Inject lateinit var apiClient: LobstersApi
private val viewModel: LobstersViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Providers(UrlLauncherAmbient provides urlLauncher) {
LobstersTheme {
val posts = mutableStateListOf<LobstersPost>()
lifecycleScope.launchWhenCreated {
withContext(Dispatchers.IO) {
posts.addAll(apiClient.getHottestPosts(1))
}
}
LobstersApp(posts)
LobstersApp(viewModel)
}
}
}
@ -49,15 +44,21 @@ class MainActivity : AppCompatActivity() {
}
@Composable
@ExperimentalCoroutinesApi
fun LobstersApp(
items: List<LobstersPost>,
viewModel: LobstersViewModel
) {
val urlLauncher = UrlLauncherAmbient.current
val state = viewModel.posts.collectAsState()
val lastIndex = state.value.lastIndex
Scaffold(
topBar = { TopAppBar({ Text(text = stringResource(R.string.app_name)) }) },
bodyContent = {
LazyColumnFor(items) { item ->
LazyColumnForIndexed(state.value) { index, item ->
if (lastIndex == index) {
viewModel.getMorePosts()
}
LobstersItem(item) { post ->
urlLauncher.launch(post.url)
}

View file

@ -0,0 +1,32 @@
package dev.msfjarvis.lobsters.data
import androidx.hilt.lifecycle.ViewModelInject
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dev.msfjarvis.lobsters.api.LobstersApi
import dev.msfjarvis.lobsters.model.LobstersPost
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
@ExperimentalCoroutinesApi
class LobstersViewModel @ViewModelInject constructor(
private val lobstersApi: LobstersApi,
) : ViewModel() {
private var apiPage = 1
private val _posts = MutableStateFlow<List<LobstersPost>>(emptyList())
val posts: StateFlow<List<LobstersPost>> get() = _posts
init {
getMorePosts()
}
fun getMorePosts() {
viewModelScope.launch {
_posts.value += lobstersApi.getHottestPosts(apiPage)
apiPage += 1
}
}
}

View file

@ -4,7 +4,8 @@ buildscript {
compose_version = '1.0.0-alpha03'
coroutines_version = '1.3.9'
dagger_version = '2.29.1'
hilt_version = '2.29-alpha'
hilt_androidx_version = '1.0.0-alpha02'
hilt_dagger_version = '2.29-alpha'
kotlin_version = '1.4.10'
lifecycle_version = '2.3.0-alpha07'
moshi_version = '1.9.3'
@ -17,7 +18,7 @@ buildscript {
dependencies {
classpath "com.android.tools.build:gradle:4.2.0-alpha12"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_dagger_version"
}
}