feat: complete DataViewModel with DataRepository integration and export/delete functionality
Build APK / build (push) Failing after 16m57s

This commit is contained in:
茂之钳
2026-05-25 07:08:54 +00:00
parent 6154104f1a
commit d738609f68
2 changed files with 132 additions and 11 deletions
@@ -7,8 +7,10 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.senstools.databinding.FragmentDataBinding
import com.senstools.presentation.adapter.DataFileAdapter
import com.senstools.presentation.viewmodel.DataFile
import com.senstools.presentation.viewmodel.DataViewModel
class DataFragment : Fragment() {
@@ -38,8 +40,8 @@ class DataFragment : Fragment() {
private fun setupRecyclerView() {
adapter = DataFileAdapter(
onItemClick = { file -> viewModel.openFile(file) },
onExportClick = { file -> viewModel.exportFile(file) },
onDeleteClick = { file -> viewModel.deleteFile(file) }
onExportClick = { file -> showExportDialog(file) },
onDeleteClick = { file -> showDeleteConfirmDialog(file) }
)
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
binding.recyclerView.adapter = adapter
@@ -49,6 +51,17 @@ class DataFragment : Fragment() {
viewModel.dataFiles.observe(viewLifecycleOwner) { files ->
adapter.submitList(files)
}
viewModel.isExporting.observe(viewLifecycleOwner) { exporting ->
binding.swipeRefresh.isEnabled = !exporting
}
viewModel.exportResult.observe(viewLifecycleOwner) { result ->
result?.let {
showToast(it)
viewModel.clearExportResult()
}
}
}
private fun setupListeners() {
@@ -58,6 +71,34 @@ class DataFragment : Fragment() {
}
}
private fun showExportDialog(file: DataFile) {
val options = arrayOf("Export to CSV", "Export to JSON")
MaterialAlertDialogBuilder(requireContext())
.setTitle("Export: " + file.name)
.setItems(options) { _, which ->
when (which) {
0 -> viewModel.exportToCSV(file)
1 -> viewModel.exportToJSON(file)
}
}
.show()
}
private fun showDeleteConfirmDialog(file: DataFile) {
MaterialAlertDialogBuilder(requireContext())
.setTitle("Delete File")
.setMessage("Delete " + file.name + "?")
.setPositiveButton("Delete") { _, _ ->
viewModel.deleteFile(file)
}
.setNegativeButton("Cancel", null)
.show()
}
private fun showToast(message: String) {
android.widget.Toast.makeText(requireContext(), message, android.widget.Toast.LENGTH_SHORT).show()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
@@ -1,37 +1,117 @@
package com.senstools.presentation.viewmodel
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.senstools.domain.repository.DataRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
class DataViewModel : ViewModel() {
class DataViewModel(application: Application) : AndroidViewModel(application) {
private val _dataFiles = MutableLiveData<List<DataFile>>()
val dataFiles: LiveData<List<DataFile>> = _dataFiles
private val _isExporting = MutableLiveData(false)
val isExporting: LiveData<Boolean> = _isExporting
private val _exportResult = MutableLiveData<String?>()
val exportResult: LiveData<String?> = _exportResult
private val dataRepository: DataRepository
init {
dataRepository = DataRepository(application.filesDir)
loadFiles()
}
private fun loadFiles() {
// Load files from storage
_dataFiles.value = emptyList()
val files = dataRepository.listDataFiles().map { info ->
DataFile(
name = info.name,
path = info.path,
size = info.size,
date = info.lastModified
)
}
_dataFiles.value = files
}
fun refreshFiles() {
loadFiles()
}
fun openFile(file: DataFile) {
// Open file for viewing
fun openFile(file: DataFile) { // placeholder
}
fun exportFile(file: DataFile) {
// Export file to CSV/JSON
fun exportToCSV(file: DataFile) {
viewModelScope.launch {
_isExporting.value = true
val result = withContext(Dispatchers.IO) {
val exportDir = File(
getApplication<Application>().filesDir,
"senstools_export"
)
exportDir.mkdirs()
val csvPath = File(exportDir, file.name.replace(".bin", ".csv")).absolutePath
val success = dataRepository.exportToCSV(file.path, csvPath)
success to csvPath
}
_exportResult.value = if (result.first) {
"CSV exported to: " + result.second
} else {
"CSV export failed"
}
_isExporting.value = false
}
}
fun exportToJSON(file: DataFile) {
viewModelScope.launch {
_isExporting.value = true
val result = withContext(Dispatchers.IO) {
val exportDir = File(
getApplication<Application>().filesDir,
"senstools_export"
)
exportDir.mkdirs()
val jsonPath = File(exportDir, file.name.replace(".bin", ".json")).absolutePath
val success = dataRepository.exportToJSON(file.path, jsonPath)
success to jsonPath
}
_exportResult.value = if (result.first) {
"JSON exported to: " + result.second
} else {
"JSON export failed"
}
_isExporting.value = false
}
}
fun deleteFile(file: DataFile) {
// Delete file
viewModelScope.launch {
withContext(Dispatchers.IO) {
dataRepository.deleteFile(file.name)
}
loadFiles()
}
}
fun deleteAll() {
viewModelScope.launch {
withContext(Dispatchers.IO) {
dataRepository.deleteAll()
}
loadFiles()
}
}
fun clearExportResult() {
_exportResult.value = null
}
}