WIP: Sets up overview view model with TodoFileRepository singleton

This commit is contained in:
Dennis Schoepf 2025-05-14 11:01:55 +02:00
parent 2da2e011bc
commit 6478ea70f9
10 changed files with 92 additions and 39 deletions

View file

@ -54,6 +54,8 @@ dependencies {
implementation(libs.androidx.navigation.compose)
implementation(libs.kotlinx.serialization)
implementation(libs.hilt.android)
implementation(libs.hilt.navigation)
ksp(libs.hilt.compiler)
testImplementation(libs.junit)

View file

@ -13,7 +13,7 @@
android:theme="@style/Theme.Plaindo"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:name=".PlaindoApplication"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.Plaindo">

View file

@ -9,9 +9,11 @@ import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.dnsc.plaindo.data.TodoFileRepository
import com.dnsc.plaindo.ui.theme.PlaindoTheme
import dagger.hilt.android.AndroidEntryPoint
const val TAG = "MainActivity"
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
private lateinit var todoFileRepository: TodoFileRepository
private lateinit var openDocumentLauncher: ActivityResultLauncher<Array<String>>
@ -19,18 +21,7 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Set up dependencies
todoFileRepository = TodoFileRepository(this)
// Draw content
enableEdgeToEdge()
setContent {
PlaindoTheme {
PlaindoApp()
}
}
// Handle init tasks
openDocumentLauncher = registerForActivityResult(
ActivityResultContracts.OpenDocument()
) { uri ->
@ -50,6 +41,13 @@ class MainActivity : ComponentActivity() {
// TODO: Move to / listen to button click for this function
openDocumentLauncher.launch(arrayOf("text/plain"))
enableEdgeToEdge()
setContent {
PlaindoTheme {
PlaindoApp()
}
}
}
}

View file

@ -2,10 +2,7 @@ package com.dnsc.plaindo
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject
@HiltAndroidApp
class PlaindoApplication: Application() {
override fun onCreate() {
super.onCreate()
}
}
class PlaindoApplication: Application()

View file

@ -2,12 +2,16 @@ package com.dnsc.plaindo.data
import android.content.Context
import android.net.Uri
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import java.io.BufferedReader
import java.io.InputStreamReader
class TodoFileRepository(val context: Context) {
var todoFileUri: Uri? = null
val todos: ArrayList<Todo> = ArrayList()
private val _todos = MutableStateFlow<List<Todo>>(emptyList())
val todos: StateFlow<List<Todo>> = _todos.asStateFlow()
fun load(uri: Uri) {
context.contentResolver.openInputStream(uri)?.use { inputStream ->

View file

@ -0,0 +1,20 @@
package com.dnsc.plaindo.di
import android.content.Context
import com.dnsc.plaindo.data.TodoFileRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object TodosModule {
@Provides
@Singleton
fun provideTodoFileRepository(@ApplicationContext context: Context): TodoFileRepository {
return TodoFileRepository(context)
}
}

View file

@ -1,18 +0,0 @@
package com.dnsc.plaindo.ui.models
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import com.dnsc.plaindo.data.Todo
import com.dnsc.plaindo.data.TodoFileRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
@HiltViewModel
class MainViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
private val todoFileRepository: TodoFileRepository
): ViewModel() {
fun getAllTodos(): List<Todo> {
return todoFileRepository.todos
}
}

View file

@ -0,0 +1,31 @@
package com.dnsc.plaindo.ui.overview
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dnsc.plaindo.data.Todo
import com.dnsc.plaindo.data.TodoFileRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import javax.inject.Inject
@HiltViewModel
class OverviewViewModel @Inject constructor(
private val todoFileRepository: TodoFileRepository
) : ViewModel() {
val todosUiState: StateFlow<OverviewUiState> = todoFileRepository.todos
.map { todos -> OverviewUiState.Success(todos) }
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = OverviewUiState.Loading
)
}
sealed interface OverviewUiState {
data object Loading : OverviewUiState
data class Success(val todos: List<Todo>) : OverviewUiState
data class Error(val message: String) : OverviewUiState // Optional error state
}

View file

@ -5,15 +5,32 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.compose.runtime.getValue
import androidx.navigation.NavHostController
import com.dnsc.plaindo.ui.models.MainViewModel
@Composable
fun PlaindoOverviewScreen(navController: NavHostController, innerPadding: PaddingValues) {
val mainViewModel: MainViewModel = hiltViewModel()
fun PlaindoOverviewScreen(navController: NavHostController, innerPadding: PaddingValues, viewModel: OverviewViewModel = hiltViewModel()) {
val uiState by viewModel.todosUiState.collectAsState()
Column(modifier = Modifier.padding(innerPadding)) {
Text(text = "Overview")
}
/*when (uiState) {
OverviewUiState.Loading -> {
// Show a loading indicator
// ...
}
is OverviewUiState.Success -> {
// Display the list of todos
TodoList(todos = uiState.todos)
}
is OverviewUiState.Error -> {
// Show an error message
// ...
}
}*/
}