refactored all states to communicate between viewmodels
This commit is contained in:
		
							parent
							
								
									25ed3dfdd2
								
							
						
					
					
						commit
						3c1bc9bb1b
					
				
					 13 changed files with 78 additions and 125 deletions
				
			
		|  | @ -1,11 +0,0 @@ | |||
| package be.ugent.sel.studeez.data | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer | ||||
| import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo | ||||
| import javax.inject.Inject | ||||
| import javax.inject.Singleton | ||||
| 
 | ||||
| @Singleton | ||||
| class EditTimerState @Inject constructor(){ | ||||
|     lateinit var timerInfo: TimerInfo | ||||
| } | ||||
							
								
								
									
										45
									
								
								app/src/main/java/be/ugent/sel/studeez/data/SelectedState.kt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/src/main/java/be/ugent/sel/studeez/data/SelectedState.kt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| package be.ugent.sel.studeez.data | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.local.models.SessionReport | ||||
| import be.ugent.sel.studeez.data.local.models.task.Subject | ||||
| import be.ugent.sel.studeez.data.local.models.task.Task | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer | ||||
| import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo | ||||
| import javax.inject.Inject | ||||
| import javax.inject.Singleton | ||||
| 
 | ||||
| /** | ||||
|  * Used to cummunicate between viewmodels. | ||||
|  */ | ||||
| abstract class SelectedState<T> { | ||||
|     abstract var value: T | ||||
|     operator fun invoke() = value | ||||
|     fun set(newValue: T) { | ||||
|         this.value = newValue | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @Singleton | ||||
| class SelectedSessionReport @Inject constructor() : SelectedState<SessionReport>() { | ||||
|     override lateinit var value: SessionReport | ||||
| } | ||||
| 
 | ||||
| @Singleton | ||||
| class SelectedTask @Inject constructor() : SelectedState<Task>() { | ||||
|     override lateinit var value: Task | ||||
| } | ||||
| 
 | ||||
| @Singleton | ||||
| class SelectedTimer @Inject constructor() : SelectedState<FunctionalTimer>() { | ||||
|     override lateinit var value: FunctionalTimer | ||||
| } | ||||
| 
 | ||||
| @Singleton | ||||
| class SelectedSubject @Inject constructor() : SelectedState<Subject>() { | ||||
|     override lateinit var value: Subject | ||||
| } | ||||
| 
 | ||||
| @Singleton | ||||
| class SelectedTimerInfo @Inject constructor() : SelectedState<TimerInfo>() { | ||||
|     override lateinit var value: TimerInfo | ||||
| } | ||||
|  | @ -1,20 +0,0 @@ | |||
| package be.ugent.sel.studeez.data | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.local.models.task.Subject | ||||
| import javax.inject.Inject | ||||
| import javax.inject.Singleton | ||||
| 
 | ||||
| /** | ||||
|  * Used to communicate the selected subject from the subject overview other screens. | ||||
|  * Because this is a singleton-class the view-models of both screens observe the same data. | ||||
|  */ | ||||
| @Singleton | ||||
| class SelectedSubject @Inject constructor() { | ||||
|     private lateinit var subject: Subject | ||||
|     operator fun invoke() = subject | ||||
|     fun set(subject: Subject) { | ||||
|         this.subject = subject | ||||
|     } | ||||
| 
 | ||||
|     fun isSet() = this::subject.isInitialized | ||||
| } | ||||
|  | @ -1,21 +0,0 @@ | |||
| package be.ugent.sel.studeez.data | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.local.models.task.Task | ||||
| import javax.inject.Inject | ||||
| import javax.inject.Singleton | ||||
| 
 | ||||
| /** | ||||
|  * Used to communicate the selected task from the task overview other screens. | ||||
|  * Because this is a singleton-class the view-models of both screens observe the same data. | ||||
|  */ | ||||
| @Singleton | ||||
| class SelectedTask @Inject constructor() { | ||||
|     private lateinit var task: Task | ||||
| 
 | ||||
|     operator fun invoke() = task | ||||
|     fun set(task: Task) { | ||||
|         this.task = task | ||||
|     } | ||||
| 
 | ||||
|     fun isSet() = this::task.isInitialized | ||||
| } | ||||
|  | @ -1,14 +0,0 @@ | |||
| package be.ugent.sel.studeez.data | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer | ||||
| import javax.inject.Inject | ||||
| import javax.inject.Singleton | ||||
| 
 | ||||
| /** | ||||
|  * Used to communicate the SelectedTimer from the selection screen to the session screen. | ||||
|  * Because this is a singleton-class the view-models of both screens observe the same data. | ||||
|  */ | ||||
| @Singleton | ||||
| class SelectedTimerState @Inject constructor(){ | ||||
|     var selectedTimer: FunctionalTimer? = null | ||||
| } | ||||
|  | @ -1,14 +0,0 @@ | |||
| package be.ugent.sel.studeez.data | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.local.models.SessionReport | ||||
| import javax.inject.Inject | ||||
| import javax.inject.Singleton | ||||
| 
 | ||||
| /** | ||||
|  * Used to communicate the SelectedTimer from the selection screen to the session screen. | ||||
|  * Because this is a singleton-class the view-models of both screens observe the same data. | ||||
|  */ | ||||
| @Singleton | ||||
| class SessionReportState @Inject constructor(){ | ||||
|     var sessionReport: SessionReport? = null | ||||
| } | ||||
|  | @ -1,9 +1,8 @@ | |||
| package be.ugent.sel.studeez.screens.session | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.SelectedSessionReport | ||||
| import be.ugent.sel.studeez.data.SelectedTask | ||||
| import be.ugent.sel.studeez.data.SelectedTimerState | ||||
| import be.ugent.sel.studeez.data.SessionReportState | ||||
| import be.ugent.sel.studeez.data.local.models.task.Task | ||||
| import be.ugent.sel.studeez.data.SelectedTimer | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer | ||||
| import be.ugent.sel.studeez.domain.LogService | ||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations | ||||
|  | @ -13,24 +12,21 @@ import javax.inject.Inject | |||
| 
 | ||||
| @HiltViewModel | ||||
| class SessionViewModel @Inject constructor( | ||||
|     private val selectedTimerState: SelectedTimerState, | ||||
|     private val sessionReportState: SessionReportState, | ||||
|     private val selectedTimer: SelectedTimer, | ||||
|     private val sessionReport: SelectedSessionReport, | ||||
|     private val selectedTask: SelectedTask, | ||||
|     logService: LogService | ||||
| ) : StudeezViewModel(logService) { | ||||
| 
 | ||||
|     private val task : Task = selectedTask() | ||||
| 
 | ||||
|     fun getTimer() : FunctionalTimer { | ||||
|         return selectedTimerState.selectedTimer!! | ||||
|     fun getTimer(): FunctionalTimer { | ||||
|         return selectedTimer() | ||||
|     } | ||||
| 
 | ||||
|     fun getTask(): String { | ||||
|         return task.name | ||||
|         return selectedTask().name | ||||
|     } | ||||
| 
 | ||||
|     fun endSession(openAndPopUp: (String, String) -> Unit) { | ||||
|         sessionReportState.sessionReport = getTimer().getSessionReport(task.subjectId, task.id) | ||||
|         sessionReport.set(getTimer().getSessionReport(selectedTask().subjectId, selectedTask().id)) | ||||
|         openAndPopUp(StudeezDestinations.SESSION_RECAP, StudeezDestinations.SESSION_SCREEN) | ||||
|     } | ||||
| } | ||||
|  | @ -1,7 +1,7 @@ | |||
| package be.ugent.sel.studeez.screens.session_recap | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.SelectedSessionReport | ||||
| import be.ugent.sel.studeez.data.SelectedTask | ||||
| import be.ugent.sel.studeez.data.SessionReportState | ||||
| import be.ugent.sel.studeez.data.local.models.SessionReport | ||||
| import be.ugent.sel.studeez.domain.LogService | ||||
| import be.ugent.sel.studeez.domain.SessionDAO | ||||
|  | @ -13,22 +13,21 @@ import javax.inject.Inject | |||
| 
 | ||||
| @HiltViewModel | ||||
| class SessionRecapViewModel @Inject constructor( | ||||
|     sessionReportState: SessionReportState, | ||||
|     private val selectedSessionReport: SelectedSessionReport, | ||||
|     private val sessionDAO: SessionDAO, | ||||
|     private val taskDAO: TaskDAO, | ||||
|     private val selectedTask: SelectedTask, | ||||
|     logService: LogService | ||||
| ) : StudeezViewModel(logService) { | ||||
| 
 | ||||
|     private val report: SessionReport = sessionReportState.sessionReport!! | ||||
| 
 | ||||
|     fun getSessionReport(): SessionReport { | ||||
|         return report | ||||
|         return selectedSessionReport() | ||||
|     } | ||||
| 
 | ||||
|     fun saveSession(open: (String, String) -> Unit) { | ||||
|         sessionDAO.saveSession(getSessionReport()) | ||||
|         val newTask = selectedTask().copy(time = selectedTask().time + report.studyTime) | ||||
|         val newTask = | ||||
|             selectedTask().copy(time = selectedTask().time + selectedSessionReport().studyTime) | ||||
|         taskDAO.updateTask(newTask) | ||||
|         open(StudeezDestinations.HOME_SCREEN, StudeezDestinations.SESSION_RECAP) | ||||
|     } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| package be.ugent.sel.studeez.screens.timer_form | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.EditTimerState | ||||
| import be.ugent.sel.studeez.data.SelectedTimerInfo | ||||
| import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo | ||||
| import be.ugent.sel.studeez.domain.LogService | ||||
| import be.ugent.sel.studeez.domain.TimerDAO | ||||
|  | @ -10,15 +10,12 @@ import javax.inject.Inject | |||
| 
 | ||||
| @HiltViewModel | ||||
| class TimerFormViewModel @Inject constructor( | ||||
|     private val editTimerState: EditTimerState, | ||||
|     private val selectedTimerInfo: SelectedTimerInfo, | ||||
|     private val timerDAO: TimerDAO, | ||||
|     logService: LogService | ||||
| ) : StudeezViewModel(logService) { | ||||
| 
 | ||||
|     private val timerInfo: TimerInfo = editTimerState.timerInfo | ||||
| 
 | ||||
|     fun getTimerInfo(): TimerInfo { | ||||
|         return timerInfo | ||||
|         return selectedTimerInfo() | ||||
|     } | ||||
| 
 | ||||
|     fun editTimer(timerInfo: TimerInfo, goBack: () -> Unit) { | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| package be.ugent.sel.studeez.screens.timer_form.timer_type_select | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.EditTimerState | ||||
| import be.ugent.sel.studeez.data.SelectedTimerInfo | ||||
| import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo | ||||
| import be.ugent.sel.studeez.domain.LogService | ||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations | ||||
|  | @ -10,13 +10,13 @@ import javax.inject.Inject | |||
| 
 | ||||
| @HiltViewModel | ||||
| class TimerTypeSelectViewModel @Inject constructor( | ||||
|     private val editTimerState: EditTimerState, | ||||
|     private val selectedTimerInfo: SelectedTimerInfo, | ||||
|     logService: LogService | ||||
| ) : StudeezViewModel(logService) { | ||||
| 
 | ||||
| 
 | ||||
|     fun onTimerTypeChosen(timerInfo: TimerInfo, open: (String) -> Unit) { | ||||
|         editTimerState.timerInfo = timerInfo | ||||
|         selectedTimerInfo.set(timerInfo) | ||||
|         open(StudeezDestinations.ADD_TIMER_SCREEN) | ||||
|     } | ||||
| } | ||||
|  | @ -1,6 +1,6 @@ | |||
| package be.ugent.sel.studeez.screens.timer_overview | ||||
| 
 | ||||
| import be.ugent.sel.studeez.data.EditTimerState | ||||
| import be.ugent.sel.studeez.data.SelectedTimerInfo | ||||
| import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo | ||||
| import be.ugent.sel.studeez.domain.ConfigurationService | ||||
| import be.ugent.sel.studeez.domain.LogService | ||||
|  | @ -15,11 +15,11 @@ import javax.inject.Inject | |||
| class TimerOverviewViewModel @Inject constructor( | ||||
|     private val configurationService: ConfigurationService, | ||||
|     private val timerDAO: TimerDAO, | ||||
|     private val editTimerState: EditTimerState, | ||||
|     private val selectedTimerInfo: SelectedTimerInfo, | ||||
|     logService: LogService | ||||
| ) : StudeezViewModel(logService) { | ||||
| 
 | ||||
|     fun getUserTimers() : Flow<List<TimerInfo>> { | ||||
|     fun getUserTimers(): Flow<List<TimerInfo>> { | ||||
|         return timerDAO.getUserTimers() | ||||
|     } | ||||
| 
 | ||||
|  | @ -27,8 +27,8 @@ class TimerOverviewViewModel @Inject constructor( | |||
|         return configurationService.getDefaultTimers() | ||||
|     } | ||||
| 
 | ||||
|     fun update(timerInfo: TimerInfo, open: (String) -> Unit)  { | ||||
|         editTimerState.timerInfo = timerInfo | ||||
|     fun update(timerInfo: TimerInfo, open: (String) -> Unit) { | ||||
|         selectedTimerInfo.set(timerInfo) | ||||
|         open(StudeezDestinations.TIMER_EDIT_SCREEN) | ||||
|     } | ||||
| 
 | ||||
|  | @ -36,7 +36,7 @@ class TimerOverviewViewModel @Inject constructor( | |||
|         open(StudeezDestinations.TIMER_TYPE_CHOOSING_SCREEN) | ||||
|     } | ||||
| 
 | ||||
|     fun delete(timerInfo: TimerInfo) =timerDAO.deleteTimer(timerInfo) | ||||
|     fun delete(timerInfo: TimerInfo) = timerDAO.deleteTimer(timerInfo) | ||||
| 
 | ||||
|     fun save(timerInfo: TimerInfo) = timerDAO.saveTimer(timerInfo) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,10 +1,8 @@ | |||
| package be.ugent.sel.studeez.screens.timer_selection | ||||
| 
 | ||||
| import androidx.compose.runtime.MutableState | ||||
| import androidx.compose.runtime.getValue | ||||
| import androidx.compose.runtime.mutableStateOf | ||||
| import androidx.compose.runtime.remember | ||||
| import be.ugent.sel.studeez.data.SelectedTimerState | ||||
| import be.ugent.sel.studeez.data.SelectedTimer | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds | ||||
| import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo | ||||
| import be.ugent.sel.studeez.domain.LogService | ||||
|  | @ -18,7 +16,7 @@ import javax.inject.Inject | |||
| @HiltViewModel | ||||
| class TimerSelectionViewModel @Inject constructor( | ||||
|     private val timerDAO: TimerDAO, | ||||
|     private val selectedTimerState: SelectedTimerState, | ||||
|     private val selectedTimer: SelectedTimer, | ||||
|     logService: LogService | ||||
| ) : StudeezViewModel(logService) { | ||||
| 
 | ||||
|  | @ -26,12 +24,12 @@ class TimerSelectionViewModel @Inject constructor( | |||
|         HoursMinutesSeconds(1, 0, 0).getTotalSeconds() | ||||
|     ) | ||||
| 
 | ||||
|     fun getAllTimers() : Flow<List<TimerInfo>> { | ||||
|     fun getAllTimers(): Flow<List<TimerInfo>> { | ||||
|         return timerDAO.getAllTimers() | ||||
|     } | ||||
| 
 | ||||
|     fun startSession(open: (String) -> Unit, timerInfo: TimerInfo) { | ||||
|         selectedTimerState.selectedTimer = timerInfo.getFunctionalTimer() | ||||
|         selectedTimer.set(timerInfo.getFunctionalTimer()) | ||||
|         open(StudeezDestinations.SESSION_SCREEN) | ||||
|     } | ||||
| } | ||||
|  | @ -1,8 +1,6 @@ | |||
| package be.ugent.sel.studeez.timer_functional | ||||
| 
 | ||||
| import android.media.MediaPlayer | ||||
| import be.ugent.sel.studeez.data.SelectedTimerState | ||||
| import be.ugent.sel.studeez.data.SessionReportState | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer | ||||
|  | @ -18,14 +16,14 @@ import org.mockito.kotlin.mock | |||
| 
 | ||||
| @ExperimentalCoroutinesApi | ||||
| class InvisibleSessionManagerTest { | ||||
|     private var timerState: SelectedTimerState = SelectedTimerState() | ||||
|     private var timerState: SelectedTimer = SelectedTimer() | ||||
|     private lateinit var viewModel: SessionViewModel | ||||
|     private var mediaPlayer: MediaPlayer = mock() | ||||
| 
 | ||||
|     @Test | ||||
|     fun InvisibleEndlessTimerTest() = runTest { | ||||
|         timerState.selectedTimer = FunctionalEndlessTimer() | ||||
|         viewModel = SessionViewModel(timerState, SessionReportState(), mock()) | ||||
|         viewModel = SessionViewModel(timerState, SessionReport(), mock()) | ||||
|         InvisibleSessionManager.setParameters(viewModel, mediaPlayer) | ||||
| 
 | ||||
|         val test = launch { | ||||
|  | @ -47,7 +45,7 @@ class InvisibleSessionManagerTest { | |||
|         val breakTime = 5 | ||||
|         val repeats = 1 | ||||
|         timerState.selectedTimer = FunctionalPomodoroTimer(studyTime, breakTime, repeats) | ||||
|         viewModel = SessionViewModel(timerState, SessionReportState(), mock()) | ||||
|         viewModel = SessionViewModel(timerState, SessionReport(), mock()) | ||||
|         InvisibleSessionManager.setParameters(viewModel, mediaPlayer) | ||||
| 
 | ||||
|         val test = launch { | ||||
|  | @ -80,7 +78,7 @@ class InvisibleSessionManagerTest { | |||
|     @Test | ||||
|     fun InvisibleCustomTimerTest() = runTest { | ||||
|         timerState.selectedTimer = FunctionalCustomTimer(5) | ||||
|         viewModel = SessionViewModel(timerState, SessionReportState(), mock()) | ||||
|         viewModel = SessionViewModel(timerState, SessionReport(), mock()) | ||||
|         InvisibleSessionManager.setParameters(viewModel, mediaPlayer) | ||||
| 
 | ||||
|         val test = launch { | ||||
|  |  | |||
		Reference in a new issue
	
	 brreynie
						brreynie