forked from stud179277/Timer
добавление открытия созданных тренировок
This commit is contained in:
parent
3078443367
commit
57f305819a
@ -34,12 +34,13 @@ class AddWorkout : AppCompatActivity() {
|
|||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
insets
|
insets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val workoutViewModel = ViewModelProvider(
|
val workoutViewModel = ViewModelProvider(
|
||||||
this,
|
this,
|
||||||
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
|
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
|
||||||
)[WorkoutViewModel::class.java]
|
)[WorkoutViewModel::class.java]
|
||||||
|
val workoutId = intent.getIntExtra("workoutId", -1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
editWorkoutView = findViewById(R.id.name_training)
|
editWorkoutView = findViewById(R.id.name_training)
|
||||||
numWorkoutView = findViewById(R.id.num_exercise)
|
numWorkoutView = findViewById(R.id.num_exercise)
|
||||||
@ -48,6 +49,27 @@ class AddWorkout : AppCompatActivity() {
|
|||||||
numSetsView = findViewById(R.id.numbers_of_sets_all)
|
numSetsView = findViewById(R.id.numbers_of_sets_all)
|
||||||
timeWorkoutView = findViewById(R.id.time_work_all)
|
timeWorkoutView = findViewById(R.id.time_work_all)
|
||||||
|
|
||||||
|
if (workoutId != -1) {
|
||||||
|
val viewModel = ViewModelProvider(
|
||||||
|
this,
|
||||||
|
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
|
||||||
|
)[WorkoutViewModel::class.java]
|
||||||
|
|
||||||
|
viewModel.allWorkouts.observe(this) { workouts ->
|
||||||
|
val workout = workouts.find { it.id == workoutId }
|
||||||
|
if (workout != null) {
|
||||||
|
editWorkoutView.setText(workout.name)
|
||||||
|
numWorkoutView.setText(workout.numExercises.toString())
|
||||||
|
numRestWorkoutView.setText(workout.restBetweenExercises.toString())
|
||||||
|
numRestSetsView.setText(workout.restBetweenApproaches.toString())
|
||||||
|
numSetsView.setText(workout.numApproaches.toString())
|
||||||
|
timeWorkoutView.setText(workout.exerciseDuration.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
val buttonSaveAll: Button = findViewById(R.id.btn_save_all)
|
val buttonSaveAll: Button = findViewById(R.id.btn_save_all)
|
||||||
buttonSaveAll.setOnClickListener {
|
buttonSaveAll.setOnClickListener {
|
||||||
@ -85,7 +107,7 @@ class AddWorkout : AppCompatActivity() {
|
|||||||
)
|
)
|
||||||
workoutViewModel.insert(newWorkout)
|
workoutViewModel.insert(newWorkout)
|
||||||
|
|
||||||
Toast.makeText(this, "Упражнение сохранено", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Тренировка сохранена", Toast.LENGTH_SHORT).show()
|
||||||
|
|
||||||
isSave = true
|
isSave = true
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ class AllTraining : AppCompatActivity() {
|
|||||||
trainingId = 0
|
trainingId = 0
|
||||||
)
|
)
|
||||||
exerciseViewModel.insert(newExercise)
|
exerciseViewModel.insert(newExercise)
|
||||||
|
//exerciseViewModel.addUnsavedExercise(newExercise)
|
||||||
Toast.makeText(this, "Упражнение сохранено", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Упражнение сохранено", Toast.LENGTH_SHORT).show()
|
||||||
isSave = true
|
isSave = true
|
||||||
finish()
|
finish()
|
||||||
|
@ -13,6 +13,7 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.timert.data.adapter.ExerciseAdapter
|
import com.example.timert.data.adapter.ExerciseAdapter
|
||||||
@ -20,10 +21,12 @@ import com.example.timert.data.entity.Training
|
|||||||
import com.example.timert.data.viewModel.ExerciseViewModel
|
import com.example.timert.data.viewModel.ExerciseViewModel
|
||||||
import com.example.timert.data.viewModel.TrainingViewModel
|
import com.example.timert.data.viewModel.TrainingViewModel
|
||||||
import com.example.timert.data.viewModel.WorkoutViewModel
|
import com.example.timert.data.viewModel.WorkoutViewModel
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class CreatingTraining : AppCompatActivity() {
|
class CreatingTraining : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var viewModel: ExerciseViewModel
|
private lateinit var viewModel: ExerciseViewModel
|
||||||
|
private lateinit var trainingViewModel: TrainingViewModel
|
||||||
|
|
||||||
private lateinit var name_training: EditText
|
private lateinit var name_training: EditText
|
||||||
private lateinit var numSets: EditText
|
private lateinit var numSets: EditText
|
||||||
@ -40,46 +43,52 @@ class CreatingTraining : AppCompatActivity() {
|
|||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
insets
|
insets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
viewModel = ViewModelProvider(
|
|
||||||
this,
|
|
||||||
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
|
|
||||||
)[ExerciseViewModel::class.java]
|
|
||||||
|
|
||||||
|
|
||||||
name_training = findViewById(R.id.name_training)
|
name_training = findViewById(R.id.name_training)
|
||||||
numSets = findViewById(R.id.numbers_of_sets)
|
numSets = findViewById(R.id.numbers_of_sets)
|
||||||
restSets = findViewById(R.id.rest_sets)
|
restSets = findViewById(R.id.rest_sets)
|
||||||
|
|
||||||
|
|
||||||
|
val recyclerView = findViewById<RecyclerView>(R.id.exercise)
|
||||||
|
val buttonSave: Button = findViewById(R.id.btn_save)
|
||||||
|
|
||||||
|
viewModel = ViewModelProvider(this)[ExerciseViewModel::class.java]
|
||||||
|
trainingViewModel = ViewModelProvider(this)[TrainingViewModel::class.java]
|
||||||
|
|
||||||
val adapter = ExerciseAdapter { id ->
|
val adapter = ExerciseAdapter { id ->
|
||||||
viewModel.deleteExerciseById(id)
|
viewModel.deleteExerciseById(id)
|
||||||
}
|
}
|
||||||
// adapter = ExerciseAdapter(this)
|
|
||||||
val recyclerView = findViewById<RecyclerView>(R.id.exercise)
|
|
||||||
recyclerView.adapter = adapter
|
recyclerView.adapter = adapter
|
||||||
recyclerView.layoutManager = LinearLayoutManager(this)
|
recyclerView.layoutManager = LinearLayoutManager(this)
|
||||||
|
val type = intent.getStringExtra("type")
|
||||||
|
val trainingId = intent.getIntExtra("trainingId", -1)
|
||||||
viewModel.allExercise.observe(this) { exercises ->
|
if (trainingId != -1) {
|
||||||
exercises?.let {
|
// Загружаем тренировку по ID
|
||||||
adapter.setExercises(it)
|
trainingViewModel.getTrainingById(trainingId).observe(this) { training ->
|
||||||
|
name_training.setText(training.name)
|
||||||
|
numSets.setText(training.numSets.toString())
|
||||||
|
restSets.setText(training.restBetweenSets.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == "trainingWithExercises") {
|
||||||
|
// Загружаем упражнения только если тренировка с упражнениями
|
||||||
|
viewModel.getExercisesByTrainingId(trainingId).observe(this) { exercises ->
|
||||||
|
adapter.setExercises(exercises)
|
||||||
|
}
|
||||||
|
viewModel.unsavedExercises.observe(this) { exercises ->
|
||||||
|
adapter.setExercises(exercises)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
adapter.setExercises(emptyList()) // у обычной тренировки нет упражнений
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Создание новой — поля пустые, список упражнений пустой
|
||||||
|
adapter.setExercises(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
val trainingViewModel = ViewModelProvider(
|
|
||||||
this,
|
|
||||||
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
|
|
||||||
)[TrainingViewModel::class.java]
|
|
||||||
|
|
||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
|
||||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
|
||||||
insets
|
|
||||||
}
|
|
||||||
val buttonSave: Button = findViewById(R.id.btn_save)
|
|
||||||
buttonSave.setOnClickListener {
|
buttonSave.setOnClickListener {
|
||||||
val name = name_training.text.toString()
|
val name = name_training.text.toString()
|
||||||
val numS = numSets.text.toString()
|
val numS = numSets.text.toString()
|
||||||
|
@ -34,7 +34,17 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
adapter = TrainingAdapter(
|
adapter = TrainingAdapter(
|
||||||
onDeleteWorkout = { id -> workoutViewModel.deleteWorkoutById(id) },
|
onDeleteWorkout = { id -> workoutViewModel.deleteWorkoutById(id) },
|
||||||
onDeleteTraining = { id -> trainingViewModel.deleteTrainingById(id) }
|
onDeleteTraining = { id -> trainingViewModel.deleteTrainingById(id) },
|
||||||
|
onWorkoutClick = { workout ->
|
||||||
|
val intent = Intent(this, AddWorkout::class.java)
|
||||||
|
intent.putExtra("workout_id", workout.id)
|
||||||
|
startActivity(intent)
|
||||||
|
},
|
||||||
|
onTrainingClick = { training ->
|
||||||
|
val intent = Intent(this, CreatingTraining::class.java)
|
||||||
|
intent.putExtra("training_id", training.id)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
val recyclerView = findViewById<RecyclerView>(R.id.workout)
|
val recyclerView = findViewById<RecyclerView>(R.id.workout)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.example.timert.data.adapter
|
package com.example.timert.data.adapter
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -9,14 +10,20 @@ import android.widget.TextView
|
|||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.example.timert.AddWorkout
|
||||||
|
import com.example.timert.CreatingTraining
|
||||||
import com.example.timert.R
|
import com.example.timert.R
|
||||||
import com.example.timert.com.example.timert.data.entity.Workout
|
import com.example.timert.com.example.timert.data.entity.Workout
|
||||||
import com.example.timert.data.TrainingItem
|
import com.example.timert.data.TrainingItem
|
||||||
import com.example.timert.data.entity.Training
|
import com.example.timert.data.entity.Training
|
||||||
import com.example.timert.data.trainingWithExercise
|
import com.example.timert.data.trainingWithExercise
|
||||||
|
|
||||||
|
|
||||||
class TrainingAdapter( private val onDeleteWorkout: (Int) -> Unit,
|
class TrainingAdapter( private val onDeleteWorkout: (Int) -> Unit,
|
||||||
private val onDeleteTraining: (Int) -> Unit
|
private val onDeleteTraining: (Int) -> Unit,
|
||||||
|
private val onWorkoutClick: (Workout) -> Unit,
|
||||||
|
private val onTrainingClick: (Training) -> Unit
|
||||||
|
|
||||||
) : ListAdapter<TrainingItem, RecyclerView.ViewHolder>(DiffCallback()) {
|
) : ListAdapter<TrainingItem, RecyclerView.ViewHolder>(DiffCallback()) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -35,8 +42,8 @@ class TrainingAdapter( private val onDeleteWorkout: (Int) -> Unit,
|
|||||||
val inflater = LayoutInflater.from(parent.context)
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
val view = inflater.inflate(R.layout.training_item_layout, parent, false) // один layout
|
val view = inflater.inflate(R.layout.training_item_layout, parent, false) // один layout
|
||||||
return when (viewType) {
|
return when (viewType) {
|
||||||
TYPE_WORKOUT -> WorkoutViewHolder(view, onDeleteWorkout)
|
TYPE_WORKOUT -> WorkoutViewHolder(view, onDeleteWorkout, onWorkoutClick)
|
||||||
TYPE_TRAINING_WITH_EXERCISES -> TrainingViewHolder(view, onDeleteTraining)
|
TYPE_TRAINING_WITH_EXERCISES -> TrainingViewHolder(view, onDeleteTraining, onTrainingClick)
|
||||||
else -> throw IllegalArgumentException("Invalid view type")
|
else -> throw IllegalArgumentException("Invalid view type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,23 +55,40 @@ class TrainingAdapter( private val onDeleteWorkout: (Int) -> Unit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WorkoutViewHolder(itemView: View, private val onDelete: (Int) -> Unit) :
|
class WorkoutViewHolder(itemView: View, private val onDelete: (Int) -> Unit,
|
||||||
|
private val onClick: (Workout) -> Unit) :
|
||||||
RecyclerView.ViewHolder(itemView) {
|
RecyclerView.ViewHolder(itemView) {
|
||||||
fun bind(workout: Workout) {
|
fun bind(workout: Workout) {
|
||||||
itemView.findViewById<TextView>(R.id.training_text).text = workout.name
|
itemView.findViewById<TextView>(R.id.training_text).text = workout.name
|
||||||
itemView.findViewById<ImageButton>(R.id.deleteButtonTraining).setOnClickListener {
|
itemView.findViewById<ImageButton>(R.id.deleteButtonTraining).setOnClickListener {
|
||||||
onDelete(workout.id)
|
onDelete(workout.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemView.setOnClickListener {
|
||||||
|
val context = itemView.context
|
||||||
|
val intent = Intent(context, AddWorkout::class.java)
|
||||||
|
intent.putExtra("workoutId", workout.id)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrainingViewHolder(itemView: View, private val onDelete: (Int) -> Unit) :
|
class TrainingViewHolder(itemView: View, private val onDelete: (Int) -> Unit,
|
||||||
|
private val onClick: (Training) -> Unit) :
|
||||||
RecyclerView.ViewHolder(itemView) {
|
RecyclerView.ViewHolder(itemView) {
|
||||||
fun bind(trainingWithExercise: trainingWithExercise) {
|
fun bind(trainingWithExercise: trainingWithExercise) {
|
||||||
|
val training = trainingWithExercise.training
|
||||||
itemView.findViewById<TextView>(R.id.training_text).text = trainingWithExercise.training.name
|
itemView.findViewById<TextView>(R.id.training_text).text = trainingWithExercise.training.name
|
||||||
itemView.findViewById<ImageButton>(R.id.deleteButtonTraining).setOnClickListener {
|
itemView.findViewById<ImageButton>(R.id.deleteButtonTraining).setOnClickListener {
|
||||||
onDelete(trainingWithExercise.training.id)
|
onDelete(trainingWithExercise.training.id)
|
||||||
}
|
}
|
||||||
|
itemView.setOnClickListener {
|
||||||
|
val context = itemView.context
|
||||||
|
val intent = Intent(context, CreatingTraining::class.java)
|
||||||
|
intent.putExtra("type", "trainingWithExercises")
|
||||||
|
intent.putExtra("trainingId", trainingWithExercise.training.id)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,4 +26,7 @@ interface ExerciseDao {
|
|||||||
|
|
||||||
@Query("UPDATE exercise_table SET trainingId = :newTrainingId WHERE trainingId = 0")
|
@Query("UPDATE exercise_table SET trainingId = :newTrainingId WHERE trainingId = 0")
|
||||||
suspend fun updateExercisesWithTrainingId(newTrainingId: Int)
|
suspend fun updateExercisesWithTrainingId(newTrainingId: Int)
|
||||||
|
|
||||||
|
@Query("SELECT * FROM exercise_table WHERE trainingId = :trainingId")
|
||||||
|
fun getExercisesByTrainingId(trainingId: Int): LiveData<List<Exercise>>
|
||||||
}
|
}
|
@ -38,4 +38,7 @@ interface TrainingDao {
|
|||||||
@Transaction
|
@Transaction
|
||||||
@Query("SELECT * FROM training")
|
@Query("SELECT * FROM training")
|
||||||
fun getTrainingsWithExercises(): LiveData<List<trainingWithExercise>>
|
fun getTrainingsWithExercises(): LiveData<List<trainingWithExercise>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM training WHERE id = :id")
|
||||||
|
fun getTrainingById(id: Int): LiveData<Training>
|
||||||
}
|
}
|
||||||
|
@ -14,4 +14,8 @@ class ExerciseRepository(private val exerciseDao:ExerciseDao){
|
|||||||
exerciseDao.deleteById(id)
|
exerciseDao.deleteById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getExercisesByTrainingId(trainingId: Int): LiveData<List<Exercise>> {
|
||||||
|
return exerciseDao.getExercisesByTrainingId(trainingId)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -20,4 +20,8 @@ class TrainingRepository(private val trainingDao: TrainingDao) {
|
|||||||
trainingDao.deleteById(id)
|
trainingDao.deleteById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTrainingById(id: Int): LiveData<Training> {
|
||||||
|
return trainingDao.getTrainingById(id)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ package com.example.timert.data.viewModel
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.example.timert.com.example.timert.data.database.AppDatabase
|
import com.example.timert.com.example.timert.data.database.AppDatabase
|
||||||
import com.example.timert.data.entity.Exercise
|
import com.example.timert.data.entity.Exercise
|
||||||
@ -12,7 +13,8 @@ import kotlinx.coroutines.launch
|
|||||||
class ExerciseViewModel(application: Application):AndroidViewModel(application){
|
class ExerciseViewModel(application: Application):AndroidViewModel(application){
|
||||||
private val repository: ExerciseRepository
|
private val repository: ExerciseRepository
|
||||||
val allExercise: LiveData<List<Exercise>>
|
val allExercise: LiveData<List<Exercise>>
|
||||||
|
private val _unsavedExercises = MutableLiveData<List<Exercise>>(emptyList())
|
||||||
|
val unsavedExercises: LiveData<List<Exercise>> = _unsavedExercises
|
||||||
init{
|
init{
|
||||||
val exercisesDao = AppDatabase.getDatabase(application).exerciseDao()
|
val exercisesDao = AppDatabase.getDatabase(application).exerciseDao()
|
||||||
repository = ExerciseRepository(exercisesDao)
|
repository = ExerciseRepository(exercisesDao)
|
||||||
@ -25,4 +27,20 @@ class ExerciseViewModel(application: Application):AndroidViewModel(application){
|
|||||||
fun deleteExerciseById(id: Int) = viewModelScope.launch {
|
fun deleteExerciseById(id: Int) = viewModelScope.launch {
|
||||||
repository.deleteExerciseById(id)
|
repository.deleteExerciseById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getExercisesByTrainingId(trainingId: Int): LiveData<List<Exercise>> {
|
||||||
|
return repository.getExercisesByTrainingId(trainingId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addUnsavedExercise(exercise: Exercise) {
|
||||||
|
_unsavedExercises.value = _unsavedExercises.value.orEmpty() + exercise
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteUnsavedExerciseById(id: Int) {
|
||||||
|
_unsavedExercises.value = _unsavedExercises.value.orEmpty().filterNot { it.id == id }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearUnsavedExercises() {
|
||||||
|
_unsavedExercises.value = emptyList()
|
||||||
|
}
|
||||||
}
|
}
|
@ -38,6 +38,10 @@ class TrainingViewModel (application: Application): AndroidViewModel(application
|
|||||||
repository.delete(training)
|
repository.delete(training)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTrainingById(id: Int): LiveData<Training> {
|
||||||
|
return repository.getTrainingById(id)
|
||||||
|
}
|
||||||
|
|
||||||
fun insertTrainingAndLinkExercises(training: Training) {
|
fun insertTrainingAndLinkExercises(training: Training) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val newId = repository.insert(training) // возвращает id
|
val newId = repository.insert(training) // возвращает id
|
||||||
|
Loading…
Reference in New Issue
Block a user