Advertisement
DroidZed

timer repo

May 5th, 2025
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 4.17 KB | Software | 0 0
  1. interface TimerRepo {
  2.  
  3.     val sharedTimerState: StateFlow<TimerGlobalState>
  4.  
  5.     suspend fun updateState(state: TimerGlobalState)
  6.  
  7.     suspend fun addOneMinute()
  8.  
  9.     suspend fun restartTimer()
  10.  
  11.     suspend fun activateTimer()
  12.  
  13.     suspend fun stopTimer(state: TimerState)
  14.  
  15.     fun resetTimer()
  16. }
  17.  
  18. class TimerRepoImpl(
  19.     private val coroutineScope: CloseableCoroutineScope,
  20.     private val prefs: PreferencesManager,
  21.     private val toaster: ToasterManager
  22. ) : TimerRepo {
  23.  
  24.     private var isInitialized = false
  25.     private var timerJob: Job? = null
  26.  
  27.     private val _timerState = MutableStateFlow(
  28.         TimerGlobalState()
  29.     )
  30.     override val sharedTimerState: StateFlow<TimerGlobalState> =
  31.         _timerState.asStateFlow()
  32.  
  33.     init {
  34.         coroutineScope.launch {
  35.             setupRepo()
  36.         }
  37.     }
  38.  
  39.     private suspend fun setupRepo() {
  40.         if (!isInitialized) {
  41.             try {
  42.                 _timerState.update {
  43.                     Json.decodeFromString<TimerGlobalState>(
  44.                         prefs.readData("TIMER_REPO_KEY", "{}")
  45.                     ).copy(
  46.                         state = TimerState.Stale
  47.                     )
  48.                 }
  49.             } catch (e: Exception) {
  50.                 KLogger.e(
  51.                     "Failed to load or parse timer state, using default.",
  52.                     e,
  53.                     tag = "TimerRepoImpl"
  54.                 )
  55.  
  56.                 _timerState.update { TimerGlobalState() }
  57.  
  58.                 try {
  59.                     prefs.deleteKey("TIMER_REPO_KEY")
  60.                 } catch (delEx: Exception) {
  61.                     KLogger.e("Failed to delete corrupted key: TIMER_REPO_KEY", delEx)
  62.                 }
  63.             }
  64.  
  65.             isInitialized = true
  66.         }
  67.     }
  68.  
  69.  
  70.     override suspend fun updateState(state: TimerGlobalState) {
  71.         _timerState.update { state }
  72.  
  73.         persistTimer()
  74.  
  75.         toaster.showShort("Timer saved")
  76.     }
  77.  
  78.  
  79.     override suspend fun addOneMinute() = when (_timerState.value.state) {
  80.         TimerState.Stale ->
  81.             toaster.showShort("Timer is zero.")
  82.  
  83.         TimerState.Paused -> {
  84.             _timerState.update {
  85.                 it.copy(
  86.                     time = _timerState.value.time + 60L
  87.                 )
  88.             }
  89.  
  90.             persistTimer()
  91.         }
  92.  
  93.         else -> Unit
  94.     }
  95.  
  96.     override suspend fun restartTimer() {
  97.         _timerState.update {
  98.             it.copy(
  99.                 state = TimerState.Stale,
  100.                 time = _timerState.value.totalTime
  101.             )
  102.         }
  103.  
  104.         persistTimer()
  105.  
  106.         toaster.showShort("Timer Replay!")
  107.     }
  108.  
  109.     override suspend fun activateTimer() {
  110.         if (_timerState.value.time == 0L) {
  111.             toaster.showShort("Add some time before starting!")
  112.             return
  113.         }
  114.  
  115.         _timerState.update { it.copy(state = TimerState.Running) }
  116.  
  117.         timerJob = timerRunner()
  118.     }
  119.  
  120.  
  121.     override suspend fun stopTimer(state: TimerState) {
  122.         timerJob?.cancel()
  123.         timerJob = null
  124.  
  125.         _timerState.update { it.copy(state = state) }
  126.  
  127.         persistTimer()
  128.     }
  129.  
  130.     override fun resetTimer() {
  131.         timerJob?.cancel()
  132.         timerJob = null
  133.  
  134.         _timerState.update {
  135.             it.copy(
  136.                 state = TimerState.Stale,
  137.                 time = 0L
  138.             )
  139.         }
  140.     }
  141.  
  142.     private suspend fun persistTimer() {
  143.         prefs.set("TIMER_REPO_KEY", Json.encodeToString(_timerState.value))
  144.     }
  145.  
  146.     private fun timerRunner(): Job = coroutineScope.launch {
  147.         while (isActive) {
  148.             val currentState = _timerState.value
  149.             if (currentState.time == 0L) {
  150.                 stopTimer(TimerState.Ended)
  151.                 break
  152.             }
  153.  
  154.             delay(1_000)
  155.             _timerState.update {
  156.                 it.copy(
  157.                     state = TimerState.Running,
  158.                     time = currentState.time - 1,
  159.                 )
  160.             }
  161.  
  162.             persistTimer()
  163.  
  164.             KLogger.d(
  165.                 "RUNNING State value: ${_timerState.value}",
  166.                 tag = "TIMER_VM"
  167.             )
  168.         }
  169.     }
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement