diff --git a/app/build.gradle b/app/build.gradle index 2159fa3..59cfbd2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,7 +4,7 @@ plugins { id 'kotlin-parcelize' // Navigation id 'androidx.navigation.safeargs.kotlin' - //Room + //Kotlin annotation processing tool for Room id 'kotlin-kapt' } @@ -14,7 +14,7 @@ android { defaultConfig { applicationId "com.practice.getup" - minSdk 22 + minSdk 23 targetSdk 33 versionCode 1 versionName "1.0" @@ -70,4 +70,9 @@ dependencies { implementation "androidx.room:room-runtime:$room_version" implementation "androidx.room:room-ktx:$room_version" kapt "androidx.room:room-compiler:$room_version" + //Koin + implementation "io.insert-koin:koin-core:$koin_version" + implementation "io.insert-koin:koin-android:$koin_version" + testImplementation "io.insert-koin:koin-test:$koin_version" + } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bd23cac..a622081 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools"> diff --git a/app/src/main/java/com/practice/getup/App.kt b/app/src/main/java/com/practice/getup/App.kt deleted file mode 100644 index b75d0da..0000000 --- a/app/src/main/java/com/practice/getup/App.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.practice.getup - -import android.app.Application -import com.practice.getup.database.WorkoutDatabase - -class App: Application() { - val workoutDatabase: WorkoutDatabase by lazy { WorkoutDatabase.getDataBase(this) } -} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/app/App.kt b/app/src/main/java/com/practice/getup/app/App.kt new file mode 100644 index 0000000..dbed913 --- /dev/null +++ b/app/src/main/java/com/practice/getup/app/App.kt @@ -0,0 +1,29 @@ +package com.practice.getup.app + +import android.app.Application +import com.practice.getup.data.db.WorkoutDatabase +import com.practice.getup.di.dataModule +import com.practice.getup.di.domainModule +import com.practice.getup.di.presentationModule +import org.koin.android.ext.koin.androidContext +import org.koin.android.ext.koin.androidLogger +import org.koin.core.context.startKoin +import org.koin.core.logger.Level + +class App: Application() { + val workoutDatabase: WorkoutDatabase by lazy { WorkoutDatabase.getDataBase(this) } + + override fun onCreate() { + super.onCreate() + + startKoin { + androidContext(this@App) + androidLogger(Level.DEBUG) + modules(listOf( + dataModule, + domainModule, + presentationModule + )) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/data/db/RoomStorage.kt b/app/src/main/java/com/practice/getup/data/db/RoomStorage.kt new file mode 100644 index 0000000..63d1f5d --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/db/RoomStorage.kt @@ -0,0 +1,20 @@ +package com.practice.getup.data.db + +import com.practice.getup.data.db.dto.WorkoutDto + +import kotlinx.coroutines.flow.Flow + +interface RoomStorage { + + suspend fun addNewWorkout(workoutDto: WorkoutDto) + + suspend fun deleteAllWorkouts() + + suspend fun deleteWorkout(workoutDto: WorkoutDto) + + fun getAllWorkouts(): Flow> + + suspend fun getWorkout(id: Int): WorkoutDto + + suspend fun updateWorkout(workoutDto: WorkoutDto) +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/database/WorkoutDao.kt b/app/src/main/java/com/practice/getup/data/db/WorkoutDao.kt similarity index 61% rename from app/src/main/java/com/practice/getup/database/WorkoutDao.kt rename to app/src/main/java/com/practice/getup/data/db/WorkoutDao.kt index 9aaf440..27c8713 100644 --- a/app/src/main/java/com/practice/getup/database/WorkoutDao.kt +++ b/app/src/main/java/com/practice/getup/data/db/WorkoutDao.kt @@ -1,4 +1,4 @@ -package com.practice.getup.database +package com.practice.getup.data.db import androidx.room.Dao import androidx.room.Delete @@ -6,25 +6,26 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Update +import com.practice.getup.data.db.dto.WorkoutDto import kotlinx.coroutines.flow.Flow @Dao interface WorkoutDao { @Insert(onConflict = OnConflictStrategy.IGNORE) - suspend fun insert(workout: Workout) + suspend fun insert(workout: WorkoutDto) @Update - suspend fun update(workout: Workout) + suspend fun update(workout: WorkoutDto) @Delete - suspend fun delete(workout: Workout) + suspend fun delete(workout: WorkoutDto) @Query("SELECT * FROM workout ORDER BY name ASC") - fun getAll(): Flow> + fun getAll(): Flow> @Query("SELECT * FROM workout WHERE id =:id") - fun getWorkout(id: Int): Flow + suspend fun getWorkout(id: Int): WorkoutDto @Query("DELETE FROM workout") suspend fun deleteAll() diff --git a/app/src/main/java/com/practice/getup/database/WorkoutDatabase.kt b/app/src/main/java/com/practice/getup/data/db/WorkoutDatabase.kt similarity index 78% rename from app/src/main/java/com/practice/getup/database/WorkoutDatabase.kt rename to app/src/main/java/com/practice/getup/data/db/WorkoutDatabase.kt index 9464314..e811cb9 100644 --- a/app/src/main/java/com/practice/getup/database/WorkoutDatabase.kt +++ b/app/src/main/java/com/practice/getup/data/db/WorkoutDatabase.kt @@ -1,11 +1,13 @@ -package com.practice.getup.database +package com.practice.getup.data.db import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase +import com.practice.getup.data.db.dto.WorkoutDto +import com.practice.getup.database.Workout -@Database(entities = [Workout::class], version = 1, exportSchema = false) +@Database(entities = [WorkoutDto::class], version = 1, exportSchema = false) abstract class WorkoutDatabase() : RoomDatabase() { abstract fun workoutDao(): WorkoutDao diff --git a/app/src/main/java/com/practice/getup/data/db/dto/WorkoutDto.kt b/app/src/main/java/com/practice/getup/data/db/dto/WorkoutDto.kt new file mode 100644 index 0000000..f261a9e --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/db/dto/WorkoutDto.kt @@ -0,0 +1,19 @@ +package com.practice.getup.data.db.dto + +import android.os.Parcelable +import androidx.annotation.NonNull +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import kotlinx.parcelize.Parcelize + +@Parcelize +@Entity(tableName = "workout") +data class WorkoutDto( + @PrimaryKey(autoGenerate = true) val id: Int = 0, + @NonNull @ColumnInfo val name: String, + @NonNull @ColumnInfo("preparing_time") val preparingTime: Int, + @NonNull @ColumnInfo("work_time") val workTime: Int, + @NonNull @ColumnInfo("rest_time") val restTime: Int, + @NonNull @ColumnInfo("number_of_sets") val numberOfSets: Int +): Parcelable diff --git a/app/src/main/java/com/practice/getup/data/db/impl/RoomStorageImpl.kt b/app/src/main/java/com/practice/getup/data/db/impl/RoomStorageImpl.kt new file mode 100644 index 0000000..b1ebe23 --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/db/impl/RoomStorageImpl.kt @@ -0,0 +1,34 @@ +package com.practice.getup.data.db.impl + +import android.content.Context +import com.practice.getup.app.App +import com.practice.getup.data.db.RoomStorage +import com.practice.getup.data.db.WorkoutDao +import com.practice.getup.data.db.dto.WorkoutDto +import kotlinx.coroutines.flow.Flow + +class RoomStorageImpl(context: Context) : RoomStorage { + + private val workoutDao: WorkoutDao = (context as App).workoutDatabase.workoutDao() + + + override suspend fun addNewWorkout(workoutDto: WorkoutDto) { + workoutDao.insert(workoutDto) + } + + override suspend fun deleteAllWorkouts() { + workoutDao.deleteAll() + } + + override suspend fun deleteWorkout(workoutDto: WorkoutDto) { + workoutDao.delete(workoutDto) + } + + override fun getAllWorkouts(): Flow> = workoutDao.getAll() + + override suspend fun getWorkout(id: Int): WorkoutDto = workoutDao.getWorkout(id) + + override suspend fun updateWorkout(workoutDto: WorkoutDto) { + workoutDao.update(workoutDto) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/data/repositories/impl/SettingsRepositoryImpl.kt b/app/src/main/java/com/practice/getup/data/repositories/impl/SettingsRepositoryImpl.kt new file mode 100644 index 0000000..8dd4769 --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/repositories/impl/SettingsRepositoryImpl.kt @@ -0,0 +1,4 @@ +package com.practice.getup.data.repositories.impl + +class SettingsRepositoryImpl { +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/data/repositories/impl/StorageRepositoryImpl.kt b/app/src/main/java/com/practice/getup/data/repositories/impl/StorageRepositoryImpl.kt new file mode 100644 index 0000000..69f4f14 --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/repositories/impl/StorageRepositoryImpl.kt @@ -0,0 +1,75 @@ +package com.practice.getup.data.repositories.impl + +import com.practice.getup.data.db.RoomStorage +import com.practice.getup.data.db.dto.WorkoutDto +import com.practice.getup.database.Workout +import com.practice.getup.domain.repositories.StorageRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class StorageRepositoryImpl(private val roomStorage: RoomStorage): StorageRepository { + + override suspend fun addNewWorkout(workout: Workout) { + val workoutDto = mapToData(workout) + roomStorage.addNewWorkout(workoutDto) + } + + override suspend fun deleteAllWorkouts() { + roomStorage.deleteAllWorkouts() + } + + override suspend fun deleteWorkout(workout: Workout) { + val workoutDto = mapToData(workout) + roomStorage.deleteWorkout(workoutDto) + } + + override fun getAllWorkouts(): Flow> { + val resultFromData = roomStorage.getAllWorkouts() + + return resultFromData.map { + + it.map { workoutDto -> + mapToDomain(workoutDto) + } + + } + } + + override suspend fun getWorkout(id: Int): Workout { + val resultFromData = roomStorage.getWorkout(id) + return mapToDomain(resultFromData) + + } + + override suspend fun updateWorkout(workout: Workout) { + val workoutDto = mapToData(workout) + roomStorage.updateWorkout(workoutDto) + } + + private fun mapToData(workout: Workout): WorkoutDto { + with(workout) { + return WorkoutDto( + id = id, + name = name, + preparingTime = preparingTime, + workTime = workTime, + restTime = restTime, + numberOfSets = numberOfSets + ) + } + } + + private fun mapToDomain(workoutDto: WorkoutDto): Workout{ + + with(workoutDto) { + return Workout( + id = id, + name = name, + preparingTime = preparingTime, + workTime = workTime, + restTime = restTime, + numberOfSets = numberOfSets + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/data/repositories/impl/TimerRepositoryImpl.kt b/app/src/main/java/com/practice/getup/data/repositories/impl/TimerRepositoryImpl.kt new file mode 100644 index 0000000..650bd88 --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/repositories/impl/TimerRepositoryImpl.kt @@ -0,0 +1,4 @@ +package com.practice.getup.data.repositories.impl + +class TimerRepositoryImpl { +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/data/settings/LocalSettings.kt b/app/src/main/java/com/practice/getup/data/settings/LocalSettings.kt new file mode 100644 index 0000000..f0837b5 --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/settings/LocalSettings.kt @@ -0,0 +1,4 @@ +package com.practice.getup.data.settings + +interface LocalSettings { +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/data/settings/impl/LocalSettingsImpl.kt b/app/src/main/java/com/practice/getup/data/settings/impl/LocalSettingsImpl.kt new file mode 100644 index 0000000..a04f269 --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/settings/impl/LocalSettingsImpl.kt @@ -0,0 +1,4 @@ +package com.practice.getup.data.settings.impl + +class LocalSettingsImpl { +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/data/timer/Timer.kt b/app/src/main/java/com/practice/getup/data/timer/Timer.kt new file mode 100644 index 0000000..4b612d6 --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/timer/Timer.kt @@ -0,0 +1,4 @@ +package com.practice.getup.data.timer + +interface Timer { +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/data/timer/TimerImpl.kt b/app/src/main/java/com/practice/getup/data/timer/TimerImpl.kt new file mode 100644 index 0000000..0d7e257 --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/timer/TimerImpl.kt @@ -0,0 +1,4 @@ +package com.practice.getup.data.timer + +class TimerImpl { +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/data/timer/TimerRepositoryImpl.kt b/app/src/main/java/com/practice/getup/data/timer/TimerRepositoryImpl.kt new file mode 100644 index 0000000..ddabe21 --- /dev/null +++ b/app/src/main/java/com/practice/getup/data/timer/TimerRepositoryImpl.kt @@ -0,0 +1,4 @@ +package com.practice.getup.data.timer + +class TimerRepositoryImpl { +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/database/Workout.kt b/app/src/main/java/com/practice/getup/database/Workout.kt new file mode 100644 index 0000000..950bb47 --- /dev/null +++ b/app/src/main/java/com/practice/getup/database/Workout.kt @@ -0,0 +1,30 @@ +package com.practice.getup.database + +import android.os.Parcelable +import androidx.annotation.NonNull +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import kotlinx.parcelize.Parcelize + +@Parcelize +data class Workout( + val id: Int = 0, + val name: String, + val preparingTime: Int, + val workTime: Int, + val restTime: Int, + val numberOfSets: Int +) : Parcelable + +/* +@Parcelize +@Entity(tableName = "workout") +data class Workout( + @PrimaryKey(autoGenerate = true) val id: Int = 0, + @NonNull @ColumnInfo val name: String, + @NonNull @ColumnInfo("preparing_time") val preparingTime: Int, + @NonNull @ColumnInfo("work_time") val workTime: Int, + @NonNull @ColumnInfo("rest_time") val restTime: Int, + @NonNull @ColumnInfo("number_of_sets") val numberOfSets: Int +): Parcelable*/ diff --git a/app/src/main/java/com/practice/getup/di/DataModule.kt b/app/src/main/java/com/practice/getup/di/DataModule.kt new file mode 100644 index 0000000..be5917e --- /dev/null +++ b/app/src/main/java/com/practice/getup/di/DataModule.kt @@ -0,0 +1,14 @@ +package com.practice.getup.di + +import com.practice.getup.data.db.RoomStorage +import com.practice.getup.data.db.impl.RoomStorageImpl +import com.practice.getup.data.repositories.impl.StorageRepositoryImpl +import com.practice.getup.domain.repositories.StorageRepository +import org.koin.dsl.module + +val dataModule = module { + + single {RoomStorageImpl(context = get())} + + single{StorageRepositoryImpl(roomStorage = get())} +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/di/DomainModule.kt b/app/src/main/java/com/practice/getup/di/DomainModule.kt new file mode 100644 index 0000000..5e497d3 --- /dev/null +++ b/app/src/main/java/com/practice/getup/di/DomainModule.kt @@ -0,0 +1,20 @@ +package com.practice.getup.di + +import com.practice.getup.domain.storage.AddNewWorkoutUseCase +import com.practice.getup.domain.storage.DeleteAllWorkoutsUseCase +import com.practice.getup.domain.storage.DeleteWorkoutUseCase +import com.practice.getup.domain.storage.GetAllWorkoutsUseCase +import com.practice.getup.domain.storage.GetWorkoutUseCase +import com.practice.getup.domain.storage.UpdateWorkoutUseCase +import org.koin.dsl.module + +val domainModule = module { + + factory { AddNewWorkoutUseCase(storageRepository = get()) } + factory { DeleteAllWorkoutsUseCase(storageRepository = get()) } + factory { DeleteWorkoutUseCase(storageRepository = get()) } + factory { GetAllWorkoutsUseCase(storageRepository = get()) } + factory { GetWorkoutUseCase(storageRepository = get()) } + factory { UpdateWorkoutUseCase(storageRepository = get()) } + +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/di/PresentationModule.kt b/app/src/main/java/com/practice/getup/di/PresentationModule.kt new file mode 100644 index 0000000..c113281 --- /dev/null +++ b/app/src/main/java/com/practice/getup/di/PresentationModule.kt @@ -0,0 +1,26 @@ +package com.practice.getup.di + + +import com.practice.getup.presentation.edit.view_model.OptionsViewModel +import com.practice.getup.presentation.main_menu.view_model.MainMenuViewModel +import org.koin.androidx.viewmodel.dsl.viewModel +import org.koin.dsl.module + +val presentationModule = module { + + viewModel { + MainMenuViewModel( + deleteAllWorkoutsUseCase = get(), + getAllWorkoutsUseCase = get() + ) + } + + viewModel { + OptionsViewModel( + addNewWorkoutUseCase = get(), + deleteWorkoutUseCase = get(), + getWorkoutUseCase = get(), + updateWorkoutUseCase = get() + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/domain/repositories/SettingsRepository.kt b/app/src/main/java/com/practice/getup/domain/repositories/SettingsRepository.kt new file mode 100644 index 0000000..e0f997e --- /dev/null +++ b/app/src/main/java/com/practice/getup/domain/repositories/SettingsRepository.kt @@ -0,0 +1,4 @@ +package com.practice.getup.domain.repositories + +interface SettingsRepository { +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/domain/repositories/StorageRepository.kt b/app/src/main/java/com/practice/getup/domain/repositories/StorageRepository.kt new file mode 100644 index 0000000..1e5339a --- /dev/null +++ b/app/src/main/java/com/practice/getup/domain/repositories/StorageRepository.kt @@ -0,0 +1,19 @@ +package com.practice.getup.domain.repositories + +import com.practice.getup.database.Workout +import kotlinx.coroutines.flow.Flow + +interface StorageRepository { + + suspend fun addNewWorkout(workout: Workout) + + suspend fun deleteAllWorkouts() + + suspend fun deleteWorkout(workout: Workout) + + fun getAllWorkouts(): Flow> + + suspend fun getWorkout(id: Int): Workout + + suspend fun updateWorkout(workout: Workout) +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/domain/repositories/TimerRepository.kt b/app/src/main/java/com/practice/getup/domain/repositories/TimerRepository.kt new file mode 100644 index 0000000..f2dd5c6 --- /dev/null +++ b/app/src/main/java/com/practice/getup/domain/repositories/TimerRepository.kt @@ -0,0 +1,4 @@ +package com.practice.getup.domain.repositories + +interface TimerRepository { +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/domain/storage/AddNewWorkoutUseCase.kt b/app/src/main/java/com/practice/getup/domain/storage/AddNewWorkoutUseCase.kt new file mode 100644 index 0000000..7b07bcf --- /dev/null +++ b/app/src/main/java/com/practice/getup/domain/storage/AddNewWorkoutUseCase.kt @@ -0,0 +1,11 @@ +package com.practice.getup.domain.storage + +import com.practice.getup.database.Workout +import com.practice.getup.domain.repositories.StorageRepository + +class AddNewWorkoutUseCase(private val storageRepository: StorageRepository) { + + suspend fun execute(workout: Workout){ + storageRepository.addNewWorkout(workout) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/domain/storage/DeleteAllWorkoutsUseCase.kt b/app/src/main/java/com/practice/getup/domain/storage/DeleteAllWorkoutsUseCase.kt new file mode 100644 index 0000000..70e0713 --- /dev/null +++ b/app/src/main/java/com/practice/getup/domain/storage/DeleteAllWorkoutsUseCase.kt @@ -0,0 +1,8 @@ +package com.practice.getup.domain.storage + +import com.practice.getup.domain.repositories.StorageRepository + +class DeleteAllWorkoutsUseCase(private val storageRepository: StorageRepository) { + + suspend fun execute() = storageRepository.deleteAllWorkouts() +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/domain/storage/DeleteWorkoutUseCase.kt b/app/src/main/java/com/practice/getup/domain/storage/DeleteWorkoutUseCase.kt new file mode 100644 index 0000000..a78f479 --- /dev/null +++ b/app/src/main/java/com/practice/getup/domain/storage/DeleteWorkoutUseCase.kt @@ -0,0 +1,9 @@ +package com.practice.getup.domain.storage + +import com.practice.getup.database.Workout +import com.practice.getup.domain.repositories.StorageRepository + +class DeleteWorkoutUseCase(private val storageRepository: StorageRepository) { + + suspend fun execute(workout: Workout) = storageRepository.deleteWorkout(workout) +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/domain/storage/GetAllWorkoutsUseCase.kt b/app/src/main/java/com/practice/getup/domain/storage/GetAllWorkoutsUseCase.kt new file mode 100644 index 0000000..04902ec --- /dev/null +++ b/app/src/main/java/com/practice/getup/domain/storage/GetAllWorkoutsUseCase.kt @@ -0,0 +1,10 @@ +package com.practice.getup.domain.storage + +import com.practice.getup.database.Workout +import com.practice.getup.domain.repositories.StorageRepository +import kotlinx.coroutines.flow.Flow + +class GetAllWorkoutsUseCase(private val storageRepository: StorageRepository) { + + fun execute(): Flow> = storageRepository.getAllWorkouts() +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/domain/storage/GetWorkoutUseCase.kt b/app/src/main/java/com/practice/getup/domain/storage/GetWorkoutUseCase.kt new file mode 100644 index 0000000..98a62fa --- /dev/null +++ b/app/src/main/java/com/practice/getup/domain/storage/GetWorkoutUseCase.kt @@ -0,0 +1,10 @@ +package com.practice.getup.domain.storage + +import com.practice.getup.database.Workout +import com.practice.getup.domain.repositories.StorageRepository +import kotlinx.coroutines.flow.Flow + +class GetWorkoutUseCase(private val storageRepository: StorageRepository) { + + suspend fun execute(id: Int): Workout = storageRepository.getWorkout(id) +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/domain/storage/UpdateWorkoutUseCase.kt b/app/src/main/java/com/practice/getup/domain/storage/UpdateWorkoutUseCase.kt new file mode 100644 index 0000000..046c668 --- /dev/null +++ b/app/src/main/java/com/practice/getup/domain/storage/UpdateWorkoutUseCase.kt @@ -0,0 +1,9 @@ +package com.practice.getup.domain.storage + +import com.practice.getup.database.Workout +import com.practice.getup.domain.repositories.StorageRepository + +class UpdateWorkoutUseCase(private val storageRepository: StorageRepository) { + + suspend fun execute(workout: Workout) = storageRepository.updateWorkout(workout) +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/presentation/WorkoutDatabaseViewModel.kt b/app/src/main/java/com/practice/getup/presentation/WorkoutDatabaseViewModel.kt index 1af6505..3434cb2 100644 --- a/app/src/main/java/com/practice/getup/presentation/WorkoutDatabaseViewModel.kt +++ b/app/src/main/java/com/practice/getup/presentation/WorkoutDatabaseViewModel.kt @@ -1,3 +1,4 @@ +/* package com.practice.getup.presentation import androidx.lifecycle.LiveData @@ -6,7 +7,7 @@ import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope import com.practice.getup.database.Workout -import com.practice.getup.database.WorkoutDao +import com.practice.getup.data.db.WorkoutDao import kotlinx.coroutines.launch import java.lang.IllegalArgumentException @@ -77,6 +78,7 @@ class WorkoutDatabaseViewModel(private val workoutDao: WorkoutDao) : ViewModel() (preparingTime.isNotBlank() && workTime.isNotBlank() && restTime.isNotBlank() && numberOfSets.isNotBlank() && preparingTime.toInt()>0 && workTime.toInt()>0 && restTime.toInt()>0 && numberOfSets.toInt()>0) + fun isNameInputValid( name: String ) = (name.isNotBlank()) @@ -134,4 +136,4 @@ class WorkoutDatabaseViewModelFactory(private val workoutDao: WorkoutDao) : return WorkoutDatabaseViewModel(workoutDao) as T } else throw IllegalArgumentException("Unknown ViewModel class") } -} \ No newline at end of file +}*/ diff --git a/app/src/main/java/com/practice/getup/presentation/edit/OptionsViewModel.kt b/app/src/main/java/com/practice/getup/presentation/edit/OptionsViewModel.kt deleted file mode 100644 index 4b29e8d..0000000 --- a/app/src/main/java/com/practice/getup/presentation/edit/OptionsViewModel.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.practice.getup.presentation.edit - -import android.text.Editable -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel - -class OptionsViewModel : ViewModel() { - - - private val _totalTime = MutableLiveData() - val totalTime: LiveData = _totalTime - - private var preparationTimeInput = - 0 - private var workTimeInput = 0 - private var restTimeInput = 0 - private var numberOfSetsInput = 0 - - init { - calculateTotalTime() - } - - fun getPreparationTimeInput(input: Editable?) { - preparationTimeInput = input.toString().toIntOrNull() ?: 0 - } - - fun getWorkTimeInput(input: Editable?) { - workTimeInput = input.toString().toIntOrNull() ?: 0 - } - - fun getRestTimeInput(input: Editable?) { - restTimeInput = input.toString().toIntOrNull() ?: 0 - } - - fun getSetsNumberInput(input: Editable?) { - numberOfSetsInput = input.toString().toIntOrNull() ?: 0 - } - - - fun calculateTotalTime() { - val totalSeconds = - (workTimeInput + restTimeInput) * numberOfSetsInput + preparationTimeInput - val secondsToShow = (totalSeconds % 60).toString().padStart(2, '0') - val minutesToShow = ((totalSeconds / 60) % 60).toString().padStart(2, '0') - val hoursToShow = (totalSeconds / 3600).toString().padStart(2, '0') - - _totalTime.value = when { - (totalSeconds / 3600) > 0 -> "$hoursToShow : $minutesToShow : $secondsToShow" - else -> "$minutesToShow : $secondsToShow" - } - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/ui/edit/OptionsFragment.kt b/app/src/main/java/com/practice/getup/presentation/edit/ui/OptionsFragment.kt similarity index 81% rename from app/src/main/java/com/practice/getup/ui/edit/OptionsFragment.kt rename to app/src/main/java/com/practice/getup/presentation/edit/ui/OptionsFragment.kt index 3ba5f12..1906313 100644 --- a/app/src/main/java/com/practice/getup/ui/edit/OptionsFragment.kt +++ b/app/src/main/java/com/practice/getup/presentation/edit/ui/OptionsFragment.kt @@ -1,4 +1,4 @@ -package com.practice.getup.ui.edit +package com.practice.getup.presentation.edit.ui import android.content.Context import android.os.Bundle @@ -10,40 +10,28 @@ import android.view.inputmethod.InputMethodManager import android.widget.TextView import androidx.core.widget.addTextChangedListener import androidx.fragment.app.Fragment -import androidx.fragment.app.activityViewModels -import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar -import com.practice.getup.App import com.practice.getup.R import com.practice.getup.database.Workout import com.practice.getup.databinding.FragmentOptionsBinding - -import com.practice.getup.presentation.edit.OptionsViewModel -import com.practice.getup.presentation.WorkoutDatabaseViewModel -import com.practice.getup.presentation.WorkoutDatabaseViewModelFactory +import com.practice.getup.presentation.edit.view_model.OptionsViewModel +import org.koin.androidx.viewmodel.ext.android.viewModel class OptionsFragment : Fragment() { private var _binding: FragmentOptionsBinding? = null private val binding get() = _binding!! - - private val viewModel: OptionsViewModel by viewModels() + private val viewModel: OptionsViewModel by viewModel() private var id = 0 private lateinit var workout: Workout - - - private val databaseViewModel: WorkoutDatabaseViewModel by activityViewModels { - WorkoutDatabaseViewModelFactory( - (activity?.application as App).workoutDatabase.workoutDao() - ) - } + private var titleSnackbar: Snackbar? = null + private var dataSnackbar: Snackbar? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - arguments?.let { id = it.getInt(ID) } @@ -60,7 +48,6 @@ class OptionsFragment : Fragment() { } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -71,7 +58,7 @@ class OptionsFragment : Fragment() { } if (id > 0) { - databaseViewModel.retrieveWorkout(id).observe(viewLifecycleOwner) { currentWorkout -> + viewModel.retrieveWorkout(id).observe(viewLifecycleOwner) { currentWorkout -> workout = currentWorkout bind(workout) } @@ -115,7 +102,7 @@ class OptionsFragment : Fragment() { } private fun isNumberInputValid(): Boolean{ - return databaseViewModel.isNumberInputValid( + return viewModel.isNumberInputValid( binding.editPreparationTime.text.toString(), binding.editWorkTime.text.toString(), binding.editRestTime.text.toString(), @@ -124,12 +111,12 @@ class OptionsFragment : Fragment() { } private fun isNameInputValid(): Boolean{ - return databaseViewModel.isNameInputValid(binding.editWorkoutName.text.toString()) + return viewModel.isNameInputValid(binding.editWorkoutName.text.toString()) } private fun addNewWorkout() { if (isNumberInputValid() && isNameInputValid()) { - databaseViewModel.addNewWorkout( + viewModel.addNewWorkout( binding.editWorkoutName.text.toString(), binding.editPreparationTime.text.toString(), binding.editWorkTime.text.toString(), @@ -139,13 +126,13 @@ class OptionsFragment : Fragment() { val action = OptionsFragmentDirections.actionOptionsFragmentToMainFragment() findNavController().navigate(action) } else if (!isNameInputValid()) { - showTextInputException() - } else showNumberInputException() + showTitleInputException() + } else showWorkoutDataInputException() } private fun updateWorkout(){ if (isNumberInputValid() && isNameInputValid()) { - databaseViewModel.updateWorkout( + viewModel.updateWorkout( id, binding.editWorkoutName.text.toString(), binding.editPreparationTime.text.toString(), @@ -156,24 +143,30 @@ class OptionsFragment : Fragment() { val action = OptionsFragmentDirections.actionOptionsFragmentToMainFragment() findNavController().navigate(action) } else if (!isNameInputValid()) { - showTextInputException() - } else showNumberInputException() + showTitleInputException() + } else showWorkoutDataInputException() } - private fun showNumberInputException() { - Snackbar.make(binding.optionsActivity, getString(R.string.no_input_message), 20000) - .setAction(R.string.snackbar_ok_button) {} - .show() + private fun showWorkoutDataInputException() { + dataSnackbar = makeSnackbar(getString(R.string.no_input_message)) + dataSnackbar?.show() hideKeyboard(binding.optionsActivity) } - private fun showTextInputException() { - Snackbar.make(binding.optionsActivity, getString(R.string.no_input_name_message), 20000) - .setAction(R.string.snackbar_ok_button) {} - .show() + private fun showTitleInputException() { + titleSnackbar = makeSnackbar(getString(R.string.no_input_name_message)) + titleSnackbar?.show() hideKeyboard(binding.optionsActivity) } + private fun makeSnackbar(text: CharSequence): Snackbar { + return Snackbar.make(binding.optionsActivity, text, 20000) + .setAction(R.string.snackbar_ok_button) {} + .setActionTextColor(resources.getColor(R.color.dark_blue, null)) + .setBackgroundTint(resources.getColor(R.color.super_soft_blue, null)) + .setTextColor(resources.getColor(R.color.black, null)) + } + private fun changeAppearance(){ if (id <= 0){ binding.optionsDeleteButton.visibility = View.GONE @@ -208,7 +201,7 @@ class OptionsFragment : Fragment() { } private fun deleteWorkout(){ - databaseViewModel.deleteWorkout(workout) + viewModel.deleteWorkout(workout) findNavController().navigateUp() } @@ -225,11 +218,12 @@ class OptionsFragment : Fragment() { override fun onDestroyView() { super.onDestroyView() + titleSnackbar?.dismiss() + dataSnackbar?.dismiss() _binding = null } companion object { - const val SHARED_PREF = "shared_preferences" const val ID = "id" } } \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/presentation/edit/view_model/OptionsViewModel.kt b/app/src/main/java/com/practice/getup/presentation/edit/view_model/OptionsViewModel.kt new file mode 100644 index 0000000..ee76b48 --- /dev/null +++ b/app/src/main/java/com/practice/getup/presentation/edit/view_model/OptionsViewModel.kt @@ -0,0 +1,177 @@ +package com.practice.getup.presentation.edit.view_model + +import android.text.Editable +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.practice.getup.database.Workout +import com.practice.getup.domain.storage.AddNewWorkoutUseCase +import com.practice.getup.domain.storage.DeleteWorkoutUseCase +import com.practice.getup.domain.storage.GetWorkoutUseCase +import com.practice.getup.domain.storage.UpdateWorkoutUseCase +import kotlinx.coroutines.launch + +class OptionsViewModel( + private val addNewWorkoutUseCase: AddNewWorkoutUseCase, + private val deleteWorkoutUseCase: DeleteWorkoutUseCase, + private val getWorkoutUseCase: GetWorkoutUseCase, + private val updateWorkoutUseCase: UpdateWorkoutUseCase +) : ViewModel() { + + + private val _totalTime = MutableLiveData() + val totalTime: LiveData = _totalTime + + private val _workout = MutableLiveData() + val workout: LiveData = _workout + + private var preparationTimeInput = + 0 + private var workTimeInput = 0 + private var restTimeInput = 0 + private var numberOfSetsInput = 0 + + init { + calculateTotalTime() + } + + fun getPreparationTimeInput(input: Editable?) { + preparationTimeInput = input.toString().toIntOrNull() ?: 0 + } + + fun getWorkTimeInput(input: Editable?) { + workTimeInput = input.toString().toIntOrNull() ?: 0 + } + + fun getRestTimeInput(input: Editable?) { + restTimeInput = input.toString().toIntOrNull() ?: 0 + } + + fun getSetsNumberInput(input: Editable?) { + numberOfSetsInput = input.toString().toIntOrNull() ?: 0 + } + + + fun calculateTotalTime() { + val totalSeconds = + (workTimeInput + restTimeInput) * numberOfSetsInput + preparationTimeInput + val secondsToShow = (totalSeconds % 60).toString().padStart(2, '0') + val minutesToShow = ((totalSeconds / 60) % 60).toString().padStart(2, '0') + val hoursToShow = (totalSeconds / 3600).toString().padStart(2, '0') + + _totalTime.value = when { + (totalSeconds / 3600) > 0 -> "$hoursToShow : $minutesToShow : $secondsToShow" + else -> "$minutesToShow : $secondsToShow" + } + } + + private fun insertWorkout(workout: Workout) { + viewModelScope.launch { + addNewWorkoutUseCase.execute(workout) + } + } + + fun retrieveWorkout(id: Int): LiveData { + viewModelScope.launch { + val result = getWorkoutUseCase.execute(id) + _workout.value = result + } + return workout + } + + fun deleteWorkout(workout: Workout){ + viewModelScope.launch { + deleteWorkoutUseCase.execute(workout) + } + } + + private fun updateWorkout(workout: Workout){ + viewModelScope.launch { + updateWorkoutUseCase.execute(workout) + } + } + + private fun getNewWorkoutInput( + name: String, + preparingTime: String, + workTime: String, + restTime: String, + numberOfSets: String + ) = Workout( + name = name, + preparingTime = preparingTime.toInt(), + workTime = workTime.toInt(), + restTime = restTime.toInt(), + numberOfSets = numberOfSets.toInt() + ) + + private fun getUpdatedWorkoutInput( + id: Int, + name: String, + preparingTime: String, + workTime: String, + restTime: String, + numberOfSets: String + ) = Workout( + id = id, + name = name, + preparingTime = preparingTime.toInt(), + workTime = workTime.toInt(), + restTime = restTime.toInt(), + numberOfSets = numberOfSets.toInt() + ) + + fun addNewWorkout( + name: String, + preparingTime: String, + workTime: String, + restTime: String, + numberOfSets: String + ) { + val newWorkout = getNewWorkoutInput( + name = name, + preparingTime = preparingTime, + workTime = workTime, + restTime = restTime, + numberOfSets = numberOfSets + ) + insertWorkout(newWorkout) + } + + fun isNumberInputValid( + preparingTime: String, + workTime: String, + restTime: String, + numberOfSets: String + ) = + (preparingTime.isNotBlank() && workTime.isNotBlank() && restTime.isNotBlank() && numberOfSets.isNotBlank() + && preparingTime.toInt()>0 && workTime.toInt()>0 && restTime.toInt()>0 && numberOfSets.toInt()>0) + + + fun isNameInputValid( + name: String + ) = (name.isNotBlank()) + + + fun updateWorkout( + id: Int, + name: String, + preparingTime: String, + workTime: String, + restTime: String, + numberOfSets: String + + ) { + val updatedWorkout = getUpdatedWorkoutInput( + id = id, + name = name, + preparingTime = preparingTime, + workTime = workTime, + restTime = restTime, + numberOfSets = numberOfSets + ) + updateWorkout(updatedWorkout) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/presentation/main/MainMenuViewModel.kt b/app/src/main/java/com/practice/getup/presentation/main/MainMenuViewModel.kt deleted file mode 100644 index 0d6bcb5..0000000 --- a/app/src/main/java/com/practice/getup/presentation/main/MainMenuViewModel.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.practice.getup.presentation.main - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel - -class MainMenuViewModel: ViewModel() { - - - -} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/ui/MainActivity.kt b/app/src/main/java/com/practice/getup/presentation/main/ui/MainActivity.kt similarity index 95% rename from app/src/main/java/com/practice/getup/ui/MainActivity.kt rename to app/src/main/java/com/practice/getup/presentation/main/ui/MainActivity.kt index 1ef9839..f30e7fb 100644 --- a/app/src/main/java/com/practice/getup/ui/MainActivity.kt +++ b/app/src/main/java/com/practice/getup/presentation/main/ui/MainActivity.kt @@ -1,4 +1,4 @@ -package com.practice.getup.ui +package com.practice.getup.presentation.main.ui import androidx.appcompat.app.AppCompatActivity diff --git a/app/src/main/java/com/practice/getup/ui/main/WorkoutListAdapter.kt b/app/src/main/java/com/practice/getup/presentation/main_menu/adapter/WorkoutListAdapter.kt similarity index 98% rename from app/src/main/java/com/practice/getup/ui/main/WorkoutListAdapter.kt rename to app/src/main/java/com/practice/getup/presentation/main_menu/adapter/WorkoutListAdapter.kt index ea78290..f926de3 100644 --- a/app/src/main/java/com/practice/getup/ui/main/WorkoutListAdapter.kt +++ b/app/src/main/java/com/practice/getup/presentation/main_menu/adapter/WorkoutListAdapter.kt @@ -1,4 +1,4 @@ -package com.practice.getup.ui.main +package com.practice.getup.presentation.main_menu.adapter import android.content.Context import android.view.LayoutInflater diff --git a/app/src/main/java/com/practice/getup/ui/main/MainFragment.kt b/app/src/main/java/com/practice/getup/presentation/main_menu/ui/MainFragment.kt similarity index 81% rename from app/src/main/java/com/practice/getup/ui/main/MainFragment.kt rename to app/src/main/java/com/practice/getup/presentation/main_menu/ui/MainFragment.kt index afc36e5..11f7e84 100644 --- a/app/src/main/java/com/practice/getup/ui/main/MainFragment.kt +++ b/app/src/main/java/com/practice/getup/presentation/main_menu/ui/MainFragment.kt @@ -1,4 +1,4 @@ -package com.practice.getup.ui.main +package com.practice.getup.presentation.main_menu.ui import android.os.Bundle @@ -12,32 +12,20 @@ import androidx.navigation.NavDirections import androidx.navigation.fragment.findNavController import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar -import com.practice.getup.App +import com.practice.getup.app.App import com.practice.getup.R import com.practice.getup.database.Workout import com.practice.getup.databinding.FragmentMainBinding -import com.practice.getup.presentation.main.MainMenuViewModel -import com.practice.getup.presentation.WorkoutDatabaseViewModel -import com.practice.getup.presentation.WorkoutDatabaseViewModelFactory +import com.practice.getup.presentation.main_menu.view_model.MainMenuViewModel +import com.practice.getup.presentation.main_menu.adapter.WorkoutListAdapter +import org.koin.androidx.viewmodel.ext.android.viewModel class MainFragment : Fragment() { private var _binding: FragmentMainBinding? = null private val binding get() = _binding!! - private val viewModel: MainMenuViewModel by viewModels() - - - private val databaseViewModel: WorkoutDatabaseViewModel by activityViewModels { - WorkoutDatabaseViewModelFactory( - (activity?.application as App).workoutDatabase.workoutDao() - ) - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - } + private val viewModel: MainMenuViewModel by viewModel() override fun onCreateView( inflater: LayoutInflater, @@ -49,7 +37,6 @@ class MainFragment : Fragment() { return binding.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -77,7 +64,7 @@ class MainFragment : Fragment() { binding.recyclerView.adapter = adapter binding.recyclerView.setHasFixedSize(true) - databaseViewModel.allWorkouts.observe(viewLifecycleOwner) { allWorkouts -> + viewModel.allWorkouts.observe(viewLifecycleOwner) { allWorkouts -> adapter.submitList(allWorkouts) manageEmptyListUi(allWorkouts) } @@ -98,12 +85,9 @@ class MainFragment : Fragment() { } else ->false } - } - } - private fun manageEmptyListUi(list: List){ if (list.isEmpty()){ binding.recyclerView.visibility = View.GONE @@ -111,7 +95,6 @@ class MainFragment : Fragment() { binding.emptyListViews.visibility = View.VISIBLE } - else { binding.emptyListViews.visibility = View.GONE binding.recyclerView.visibility = View.VISIBLE @@ -127,7 +110,7 @@ class MainFragment : Fragment() { .setCancelable(false) .setNegativeButton(getString(R.string.answer_no)) { _, _ -> } .setPositiveButton(getString(R.string.answer_yes)) { _, _ -> - databaseViewModel.deleteAll() + viewModel.deleteAll() } .show() } @@ -140,8 +123,4 @@ class MainFragment : Fragment() { super.onDestroyView() _binding = null } - - companion object { - const val SHARED_PREF = "shared_preferences" - } } \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/presentation/main_menu/view_model/MainMenuViewModel.kt b/app/src/main/java/com/practice/getup/presentation/main_menu/view_model/MainMenuViewModel.kt new file mode 100644 index 0000000..76e480c --- /dev/null +++ b/app/src/main/java/com/practice/getup/presentation/main_menu/view_model/MainMenuViewModel.kt @@ -0,0 +1,32 @@ +package com.practice.getup.presentation.main_menu.view_model + +import androidx.lifecycle.LiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.asLiveData +import androidx.lifecycle.viewModelScope +import com.practice.getup.database.Workout +import com.practice.getup.domain.storage.AddNewWorkoutUseCase +import com.practice.getup.domain.storage.DeleteAllWorkoutsUseCase +import com.practice.getup.domain.storage.DeleteWorkoutUseCase +import com.practice.getup.domain.storage.GetAllWorkoutsUseCase +import com.practice.getup.domain.storage.GetWorkoutUseCase +import com.practice.getup.domain.storage.UpdateWorkoutUseCase +import kotlinx.coroutines.launch + +class MainMenuViewModel( + private val deleteAllWorkoutsUseCase: DeleteAllWorkoutsUseCase, + getAllWorkoutsUseCase: GetAllWorkoutsUseCase, + + +): ViewModel() { + + val allWorkouts: LiveData> = getAllWorkoutsUseCase.execute().asLiveData() + + + fun deleteAll(){ + viewModelScope.launch { + deleteAllWorkoutsUseCase.execute() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/practice/getup/ui/settings/SettingsFragment.kt b/app/src/main/java/com/practice/getup/presentation/settings/ui/SettingsFragment.kt similarity index 90% rename from app/src/main/java/com/practice/getup/ui/settings/SettingsFragment.kt rename to app/src/main/java/com/practice/getup/presentation/settings/ui/SettingsFragment.kt index 0b00fca..6694875 100644 --- a/app/src/main/java/com/practice/getup/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/practice/getup/presentation/settings/ui/SettingsFragment.kt @@ -1,4 +1,4 @@ -package com.practice.getup.ui.settings +package com.practice.getup.presentation.settings.ui import android.os.Bundle import androidx.fragment.app.Fragment @@ -8,7 +8,7 @@ import android.view.ViewGroup import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.practice.getup.databinding.FragmentSettingsBinding -import com.practice.getup.presentation.settings.SettingsViewModel +import com.practice.getup.presentation.settings.view_model.SettingsViewModel class SettingsFragment : Fragment() { diff --git a/app/src/main/java/com/practice/getup/presentation/settings/SettingsViewModel.kt b/app/src/main/java/com/practice/getup/presentation/settings/view_model/SettingsViewModel.kt similarity index 57% rename from app/src/main/java/com/practice/getup/presentation/settings/SettingsViewModel.kt rename to app/src/main/java/com/practice/getup/presentation/settings/view_model/SettingsViewModel.kt index aec5ae8..48684c5 100644 --- a/app/src/main/java/com/practice/getup/presentation/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/practice/getup/presentation/settings/view_model/SettingsViewModel.kt @@ -1,4 +1,4 @@ -package com.practice.getup.presentation.settings +package com.practice.getup.presentation.settings.view_model import androidx.lifecycle.ViewModel diff --git a/app/src/main/java/com/practice/getup/ui/timer/WorkoutAdapter.kt b/app/src/main/java/com/practice/getup/presentation/timer/adapter/WorkoutAdapter.kt similarity index 98% rename from app/src/main/java/com/practice/getup/ui/timer/WorkoutAdapter.kt rename to app/src/main/java/com/practice/getup/presentation/timer/adapter/WorkoutAdapter.kt index 9b4a9a7..9ef7eab 100644 --- a/app/src/main/java/com/practice/getup/ui/timer/WorkoutAdapter.kt +++ b/app/src/main/java/com/practice/getup/presentation/timer/adapter/WorkoutAdapter.kt @@ -1,4 +1,4 @@ -package com.practice.getup.adapters +package com.practice.getup.presentation.timer.adapter import android.content.Context import android.graphics.Color diff --git a/app/src/main/java/com/practice/getup/models/SoundStages.kt b/app/src/main/java/com/practice/getup/presentation/timer/models/SoundStages.kt similarity index 57% rename from app/src/main/java/com/practice/getup/models/SoundStages.kt rename to app/src/main/java/com/practice/getup/presentation/timer/models/SoundStages.kt index 1639596..f10ce7b 100644 --- a/app/src/main/java/com/practice/getup/models/SoundStages.kt +++ b/app/src/main/java/com/practice/getup/presentation/timer/models/SoundStages.kt @@ -1,4 +1,4 @@ -package com.practice.getup.models +package com.practice.getup.presentation.timer.models enum class SoundStages { COUNTDOWN, diff --git a/app/src/main/java/com/practice/getup/models/TimerStages.kt b/app/src/main/java/com/practice/getup/presentation/timer/models/TimerStages.kt similarity index 59% rename from app/src/main/java/com/practice/getup/models/TimerStages.kt rename to app/src/main/java/com/practice/getup/presentation/timer/models/TimerStages.kt index c8191ac..180c78f 100644 --- a/app/src/main/java/com/practice/getup/models/TimerStages.kt +++ b/app/src/main/java/com/practice/getup/presentation/timer/models/TimerStages.kt @@ -1,4 +1,4 @@ -package com.practice.getup.models +package com.practice.getup.presentation.timer.models enum class TimerStages { PREPARATION, diff --git a/app/src/main/java/com/practice/getup/ui/timer/WorkoutFragment.kt b/app/src/main/java/com/practice/getup/presentation/timer/ui/WorkoutFragment.kt similarity index 84% rename from app/src/main/java/com/practice/getup/ui/timer/WorkoutFragment.kt rename to app/src/main/java/com/practice/getup/presentation/timer/ui/WorkoutFragment.kt index 5ac84b5..2408f0b 100644 --- a/app/src/main/java/com/practice/getup/ui/timer/WorkoutFragment.kt +++ b/app/src/main/java/com/practice/getup/presentation/timer/ui/WorkoutFragment.kt @@ -1,4 +1,4 @@ -package com.practice.getup.ui.timer +package com.practice.getup.presentation.timer.ui import android.media.MediaPlayer @@ -14,14 +14,13 @@ import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.practice.getup.R -import com.practice.getup.adapters.WorkoutAdapter +import com.practice.getup.presentation.timer.adapter.WorkoutAdapter import com.practice.getup.database.Workout import com.practice.getup.databinding.FragmentWorkoutBinding - -import com.practice.getup.models.SoundStages -import com.practice.getup.models.TimerStages -import com.practice.getup.viewModels.ViewModelFactoryFragments -import com.practice.getup.viewModels.WorkoutViewModel +import com.practice.getup.presentation.timer.models.SoundStages +import com.practice.getup.presentation.timer.models.TimerStages +import com.practice.getup.presentation.timer.view_model.ViewModelFactoryFragments +import com.practice.getup.presentation.timer.view_model.WorkoutViewModel import kotlinx.coroutines.Runnable @@ -106,8 +105,11 @@ class WorkoutFragment : Fragment() { viewModel.startTimer() } + binding.pauseButton.setOnClickListener { viewModel.pauseTimer() } + binding.restartButton.setOnClickListener { viewModel.restartTimer() } + binding.backButton.setOnClickListener { showFinishConfirmationDialog() } @@ -186,17 +188,24 @@ class WorkoutFragment : Fragment() { } } - private fun showFinishConfirmationDialog(){ - MaterialAlertDialogBuilder(requireContext()) - .setTitle(getString(R.string.alert_dialog_title)) - .setMessage(getString(R.string.alert_dialog_message_finish)) - .setCancelable(false) - .setNegativeButton(getString(R.string.answer_no)){_,_ ->} - .setPositiveButton(getString(R.string.answer_yes)){_,_ -> - val action = WorkoutFragmentDirections.actionWorkoutFragmentToMainFragment() - findNavController().navigate(action) - } - .show() + private fun showFinishConfirmationDialog() { + val action = WorkoutFragmentDirections.actionWorkoutFragmentToMainFragment() + + if (viewModel.timerStage.value == TimerStages.PREPARATION) { + findNavController().navigate(action) + } else { + MaterialAlertDialogBuilder(requireContext()) + .setTitle(getString(R.string.alert_dialog_title)) + .setMessage(getString(R.string.alert_dialog_message_finish)) + .setCancelable(false) + .setNegativeButton(getString(R.string.answer_no)) { _, _ -> } + .setPositiveButton(getString(R.string.answer_yes)) { _, _ -> + val action = WorkoutFragmentDirections.actionWorkoutFragmentToMainFragment() + findNavController().navigate(action) + } + .show() + } + } private fun createMediaPlayer(soundRes: Int){ diff --git a/app/src/main/java/com/practice/getup/presentation/timer/WorkoutViewModel.kt b/app/src/main/java/com/practice/getup/presentation/timer/view_model/WorkoutViewModel.kt similarity index 97% rename from app/src/main/java/com/practice/getup/presentation/timer/WorkoutViewModel.kt rename to app/src/main/java/com/practice/getup/presentation/timer/view_model/WorkoutViewModel.kt index 26f6a64..99f58c8 100644 --- a/app/src/main/java/com/practice/getup/presentation/timer/WorkoutViewModel.kt +++ b/app/src/main/java/com/practice/getup/presentation/timer/view_model/WorkoutViewModel.kt @@ -1,4 +1,4 @@ -package com.practice.getup.viewModels +package com.practice.getup.presentation.timer.view_model import android.os.CountDownTimer import androidx.lifecycle.LiveData @@ -7,10 +7,10 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import com.practice.getup.R import com.practice.getup.models.Stage -import com.practice.getup.models.TimerStages +import com.practice.getup.presentation.timer.models.TimerStages import com.practice.getup.utils.UiText import com.practice.getup.database.Workout -import com.practice.getup.models.SoundStages +import com.practice.getup.presentation.timer.models.SoundStages import java.lang.IllegalArgumentException class WorkoutViewModel(private val workout: Workout) : ViewModel() { @@ -58,8 +58,6 @@ class WorkoutViewModel(private val workout: Workout) : ViewModel() { createListOfStages(_currentStagePosition.value ?: (numberOfSets * 2 + 3)) } - - fun startTimer() { if (isTimerOn) return diff --git a/app/src/main/res/layout-land/fragment_workout.xml b/app/src/main/res/layout-land/fragment_workout.xml index 82080ac..a240113 100644 --- a/app/src/main/res/layout-land/fragment_workout.xml +++ b/app/src/main/res/layout-land/fragment_workout.xml @@ -5,7 +5,7 @@ android:id="@+id/constraint_layout" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.timer.WorkoutFragment"> + tools:context=".presentation.timer.ui.WorkoutFragment"> + tools:context=".presentation.main.ui.MainActivity"> + tools:context=".presentation.main_menu.ui.MainFragment"> + tools:context=".presentation.edit.ui.OptionsFragment"> @@ -34,7 +33,6 @@ android:id="@+id/edit_workout_name" android:layout_width="match_parent" android:layout_height="match_parent" - android:inputType="text" android:maxLength="22" android:textColor="@color/black" /> diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index 434254d..dcf23fc 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.settings.SettingsFragment" + tools:context=".presentation.settings.ui.SettingsFragment" > + tools:context=".presentation.timer.ui.WorkoutFragment"> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c10e163..ff43d6d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -77,9 +77,9 @@ ADD DELETE Введите название тренировки - Заполните поля, кроме названия тренировки, ненулевыми значениями + Заполните поля данных о тренировке ненулевыми значениями Введите значение больше ноля - Ненулевое + Больше ноля 0 : 0 : 0 TOTAL TIME UPDATE diff --git a/build.gradle b/build.gradle index 4de0405..a365895 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,7 @@ buildscript { lifecycle_version = '2.6.1' core_ktx_version = '1.10.0' material_version = '1.9.0' + koin_version ='3.4.2' } dependencies { classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"