Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5e8ee8c
[chore] 캐릭터 별 음성 추가
likppi10 Nov 28, 2025
d2670c4
[chore] 캐릭터 별 오렌지 배경 이미지 수정 및 추가
likppi10 Nov 28, 2025
3264e05
[chore] 집중 모드 관련 이미지 추가
likppi10 Nov 28, 2025
b64ff55
[fix] 타이머 레포 수정
likppi10 Nov 28, 2025
f3276d6
[fix] 유스케이스 추가
likppi10 Nov 28, 2025
7a8bd61
[fix] 타임피커 개선 상태 호이스팅
likppi10 Nov 28, 2025
e8ccb8a
[chore] 집중 모드 관련 이미지 추가
likppi10 Nov 28, 2025
c33951c
[fix] 컴포넌트 수정
likppi10 Nov 28, 2025
b9ad4b4
[chore] 색 추가
likppi10 Nov 28, 2025
2b4a1a5
[fix] 디자인 시스템 수정
likppi10 Nov 28, 2025
ee3e066
[chore] 멘트 연결
likppi10 Nov 28, 2025
8c2f538
[chore] 멘트 추가
likppi10 Nov 28, 2025
4b64c5d
[chore] 멘트 추가
likppi10 Nov 28, 2025
2fdbdd3
[fix] 타이머 설정 수정
likppi10 Nov 28, 2025
3b90e45
[fix] 타이머 화면 수정
likppi10 Nov 28, 2025
1b6ad7f
[fix] 알람 화면 수정
likppi10 Nov 28, 2025
de7afbd
[fix] 타이머 수정
likppi10 Nov 28, 2025
37836ae
[fix] 코인 모듈 수정
likppi10 Nov 28, 2025
eaa4ab1
[chore] 휴식 모드 미선택 레벨 캐릭터 이미지 변경
likppi10 Dec 11, 2025
15656fc
[fix] 나나 차차 성격 변경
likppi10 Dec 11, 2025
1166699
[chore] 집중 모드 멘트 추가
likppi10 Dec 11, 2025
30756da
[fix] 인터벌 타이머 여부 저장
likppi10 Dec 11, 2025
1768852
[fix] 집중 모드 멘트 추가
likppi10 Dec 11, 2025
10041e1
[fix] 집중 모드 멘트 텍스트 적용
likppi10 Dec 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
Expand All @@ -15,17 +16,27 @@ class TimerDataStore(private val dataStore: DataStore<Preferences>) {
private val characterIdxKey = intPreferencesKey("character_idx_data")
private val levelKey = intPreferencesKey("level_data")
private val levelIdxKey = intPreferencesKey("level_idx_data")
private val isIntervalTimerKey = booleanPreferencesKey("is_interval_timer_data")
private val hourKey = intPreferencesKey("hour_data")
private val settingHourKey = intPreferencesKey("setting_hour_data")
private val minuteKey = intPreferencesKey("minute_data")
private val settingMinuteKey = intPreferencesKey("setting_minute_data")
private val isRestCompletedKey = booleanPreferencesKey("is_rest_completed__data")
private val timerModeKey = stringPreferencesKey("timer_mode")
private val timerTypeKey = stringPreferencesKey("timer_type")
private val snoozeCountKey = intPreferencesKey("snooze_count_data")

companion object {
const val DEFAULT_IS_SETTING_TIMER = false
const val DEFAULT_CHARACTER_IDX = 0
const val DEFAULT_LEVEL = 1
const val DEFAULT_LEVEL_IDX = 0
const val DEFAULT_IS_INTERVAL_TIMER = false
const val DEFAULT_HOUR = 0
const val DEFAULT_MINUTE = 30
const val DEFAULT_IS_REST_COMPLETED = false
const val DEFAULT_TIMER_MODE = "REST"
const val DEFAULT_TIMER_TYPE = "NORMAL"
const val DEFAULT_SNOOZE_COUNT = 0
}

Expand Down Expand Up @@ -81,6 +92,18 @@ class TimerDataStore(private val dataStore: DataStore<Preferences>) {
}
}

fun getIsIntervalTimer(): Flow<Boolean> {
return dataStore.data.map { preferences ->
preferences[isIntervalTimerKey] ?: DEFAULT_IS_INTERVAL_TIMER
}
}

suspend fun setIsIntervalTimer(isIntervalTimer: Boolean) {
dataStore.edit { preferences ->
preferences[isIntervalTimerKey] = isIntervalTimer
}
}

fun getHour(): Flow<Int> {
return dataStore.data.map { preferences ->
preferences[hourKey] ?: DEFAULT_HOUR
Expand All @@ -105,6 +128,66 @@ class TimerDataStore(private val dataStore: DataStore<Preferences>) {
}
}

fun getSettingHour(): Flow<Int> {
return dataStore.data.map { preferences ->
preferences[settingHourKey] ?: DEFAULT_HOUR
}
}

suspend fun setSettingHour(settingHour: Int) {
dataStore.edit { preferences ->
preferences[settingHourKey] = settingHour
}
}

fun getSettingMinute(): Flow<Int> {
return dataStore.data.map { preferences ->
preferences[settingMinuteKey] ?: DEFAULT_MINUTE
}
}

suspend fun setSettingMinute(settingMinute: Int) {
dataStore.edit { preferences ->
preferences[settingMinuteKey] = settingMinute
}
}

fun getIsRestCompleted(): Flow<Boolean> {
return dataStore.data.map { preferences ->
preferences[isRestCompletedKey] ?: DEFAULT_IS_REST_COMPLETED
}
}

suspend fun seIsRestCompleted(isRestCompleted: Boolean) {
dataStore.edit { preferences ->
preferences[isRestCompletedKey] = isRestCompleted
}
}

fun getTimerMode(): Flow<String> {
return dataStore.data.map { preferences ->
preferences[timerModeKey] ?: DEFAULT_TIMER_MODE
}
}

suspend fun setTimerMode(timerMode: String) {
dataStore.edit { preferences ->
preferences[timerModeKey] = timerMode
}
}

fun getTimerType(): Flow<String?> {
return dataStore.data.map { preferences ->
preferences[timerTypeKey]
}
}

suspend fun setTimerType(timerType: String) {
dataStore.edit { preferences ->
preferences[timerTypeKey] = timerType
}
}

fun getSnoozeCount(): Flow<Int> {
return dataStore.data.map { preferences ->
preferences[snoozeCountKey] ?: DEFAULT_SNOOZE_COUNT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ import android.util.Log
import com.ggaebiz.ggaebiz.data.datastore.TimerDataStore
import com.ggaebiz.ggaebiz.data.datastore.TimerDataStore.Companion.DEFAULT_CHARACTER_IDX
import com.ggaebiz.ggaebiz.data.datastore.TimerDataStore.Companion.DEFAULT_HOUR
import com.ggaebiz.ggaebiz.data.datastore.TimerDataStore.Companion.DEFAULT_IS_INTERVAL_TIMER
import com.ggaebiz.ggaebiz.data.datastore.TimerDataStore.Companion.DEFAULT_IS_REST_COMPLETED
import com.ggaebiz.ggaebiz.data.datastore.TimerDataStore.Companion.DEFAULT_IS_SETTING_TIMER
import com.ggaebiz.ggaebiz.data.datastore.TimerDataStore.Companion.DEFAULT_LEVEL
import com.ggaebiz.ggaebiz.data.datastore.TimerDataStore.Companion.DEFAULT_MINUTE
import com.ggaebiz.ggaebiz.domain.repository.TimerRepository
import com.ggaebiz.ggaebiz.presentation.ui.setting.TimerMode
import com.ggaebiz.ggaebiz.presentation.ui.setting.toTimerMode
import com.ggaebiz.ggaebiz.presentation.ui.setting.toTimerModeString
import kotlinx.coroutines.flow.first

class TimerRepositoryImpl(
Expand Down Expand Up @@ -99,6 +104,78 @@ class TimerRepositoryImpl(
}
}

override suspend fun getSettingHour(): Int {
return try {
timerDataStore.getSettingHour().first()
} catch (e: Exception) {
Log.e("TimerRepositoryImpl", "Error fetching timer data", e)
DEFAULT_HOUR
}
}

override suspend fun setSettingHour(settingHour: Int) {
try {
timerDataStore.setSettingHour(settingHour)
} catch (e: Exception) {
Log.e("TimerRepositoryImpl", "Error updating timer data", e)
}
}

override suspend fun getSettingMinute(): Int {
return try {
timerDataStore.getSettingMinute().first()
} catch (e: Exception) {
Log.e("TimerRepositoryImpl", "Error fetching timer data", e)
DEFAULT_MINUTE
}
}

override suspend fun setSettingMinute(settingMinute: Int) {
try {
timerDataStore.setSettingMinute(settingMinute)
} catch (e: Exception) {
Log.e("TimerRepositoryImpl", "Error updating timer data", e)
}
}

override suspend fun getIsRestCompleted(): Boolean {
return try {
timerDataStore.getIsRestCompleted().first()
} catch (e: Exception) {
Log.e("TimerRepositoryImpl", "Error fetching timer data", e)
DEFAULT_IS_REST_COMPLETED
}
}

override suspend fun setIsRestCompleted(isRestCompleted: Boolean) {
try {
timerDataStore.seIsRestCompleted(isRestCompleted)
} catch (e: Exception) {
Log.e("TimerRepositoryImpl", "Error updating timer data", e)
}
}

override suspend fun getTimerMode(): TimerMode {
return try {
val modeValue = timerDataStore.getTimerMode().first()
val typeValue = timerDataStore.getTimerType().first()
toTimerMode(modeValue, typeValue)
} catch (e: Exception) {
Log.e("TimerRepositoryImpl", "Error fetching timer data", e)
toTimerMode(TimerDataStore.DEFAULT_TIMER_MODE, TimerDataStore.DEFAULT_TIMER_TYPE)
}
}

override suspend fun setTimerMode(timerMode: TimerMode) {
try {
val (modeValue, typeValue) = toTimerModeString(timerMode)
timerDataStore.setTimerMode(modeValue)
timerDataStore.setTimerType(typeValue)
} catch (e: Exception) {
Log.e("TimerRepositoryImpl", "Error updating timer data", e)
}
}

override suspend fun getSnoozeCount(): Int {
return try {
timerDataStore.getSnoozeCount().first()
Expand All @@ -122,6 +199,23 @@ class TimerRepositoryImpl(
Log.e("TimerRepositoryImpl", "Error updating timer data", e)
}
}

override suspend fun getIsIntervalTimer(): Boolean {
return try {
timerDataStore.getIsIntervalTimer().first()
} catch (e: Exception) {
Log.e("TimerRepositoryImpl", "Error updating timer data", e)
DEFAULT_IS_INTERVAL_TIMER
}
}

override suspend fun setIsIntervalTimer(isIntervalTimer: Boolean) {
try {
timerDataStore.setIsIntervalTimer(isIntervalTimer)
} catch (e: Exception) {
Log.e("TimerRepositoryImpl", "Error updating timer data", e)
}
}
}


Expand Down
22 changes: 15 additions & 7 deletions app/src/main/java/com/ggaebiz/ggaebiz/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ import com.ggaebiz.ggaebiz.domain.usecase.EndTimerUseCase
import com.ggaebiz.ggaebiz.domain.usecase.GetAudioResIdUseCase
import com.ggaebiz.ggaebiz.domain.usecase.GetCharacterIdxUseCase
import com.ggaebiz.ggaebiz.domain.usecase.GetSnoozeCountUseCase
import com.ggaebiz.ggaebiz.domain.usecase.GetTimerSettingUseCase
import com.ggaebiz.ggaebiz.domain.usecase.GetCurrentTimerUseCase
import com.ggaebiz.ggaebiz.domain.usecase.GetIsRestCompletedUseCase
import com.ggaebiz.ggaebiz.domain.usecase.GetSettingTimerUseCase
import com.ggaebiz.ggaebiz.domain.usecase.SelectCharacterIdxUseCase
import com.ggaebiz.ggaebiz.domain.usecase.SetSnoozeCountUseCase
import com.ggaebiz.ggaebiz.domain.usecase.SetTimerSettingUseCase
import com.ggaebiz.ggaebiz.domain.usecase.SetCurrentTimerUseCase
import com.ggaebiz.ggaebiz.domain.usecase.SetIsRestCompletedUseCase
import com.ggaebiz.ggaebiz.domain.usecase.SetSettingTimerUseCase
import com.ggaebiz.ggaebiz.presentation.service.TimerServiceManager
import com.ggaebiz.ggaebiz.presentation.ui.alarm.AlarmViewModel
import com.ggaebiz.ggaebiz.presentation.ui.config.ConfigViewModel
Expand Down Expand Up @@ -58,18 +62,22 @@ val appModule = module {
factory { GetAudioResIdUseCase(get()) }
factory { SelectCharacterIdxUseCase(get()) }
factory { GetCharacterIdxUseCase(get()) }
factory { SetTimerSettingUseCase(get()) }
factory { GetCurrentTimerUseCase(get()) }
factory { SetCurrentTimerUseCase(get()) }
factory { EndTimerUseCase(get()) }
factory { GetTimerSettingUseCase(get()) }
factory { GetSettingTimerUseCase(get()) }
factory { SetSettingTimerUseCase(get()) }
factory { GetIsRestCompletedUseCase(get()) }
factory { SetIsRestCompletedUseCase(get()) }
factory { SetSnoozeCountUseCase(get()) }
factory { GetSnoozeCountUseCase(get()) }

viewModel { HomeViewModel(get(), get(), get()) }
viewModel { SettingViewModel(get(), get(), get()) }
viewModel { SettingViewModel(get(), get(), get(), get(), get()) }
viewModel { SplashViewModel(get()) }
viewModel { OnboardingViewModel(get()) }
viewModel { TimerViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { AlarmViewModel(get(), get(), get(), get(), get()) }
viewModel { TimerViewModel(get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { AlarmViewModel(get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { ConfigViewModel(get()) }

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.ggaebiz.ggaebiz.domain.repository

import com.ggaebiz.ggaebiz.presentation.ui.setting.TimerMode

interface TimerRepository {

suspend fun getIsSettingTimer(): Boolean
Expand All @@ -17,8 +19,23 @@ interface TimerRepository {
suspend fun getMinute(): Int
suspend fun setMinute(minute: Int)

suspend fun getSettingHour(): Int
suspend fun setSettingHour(settingHour: Int)

suspend fun getSettingMinute(): Int
suspend fun setSettingMinute(settingMinute: Int)

suspend fun getIsRestCompleted(): Boolean
suspend fun setIsRestCompleted(isRestCompleted: Boolean)

suspend fun getTimerMode(): TimerMode
suspend fun setTimerMode(timerMode: TimerMode)

suspend fun getSnoozeCount(): Int
suspend fun setSnoozeCount(count: Int)

suspend fun getLevelIdx(): Int

suspend fun getIsIntervalTimer(): Boolean
suspend fun setIsIntervalTimer(isIntervalTimer: Boolean)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.ggaebiz.ggaebiz.domain.usecase

import com.ggaebiz.ggaebiz.domain.repository.TimerRepository
import com.ggaebiz.ggaebiz.presentation.ui.home.Quadruple
import com.ggaebiz.ggaebiz.presentation.ui.setting.TimerMode

class GetCurrentTimerUseCase(private val repository: TimerRepository) {
suspend operator fun invoke(): Quadruple<Int, Int, Int, TimerMode> {
repository.run {
return Quadruple(getLevel(), getHour(), getMinute(), getTimerMode())
}
}

suspend fun getLevelIdx(): Int {
repository.run {
return getLevelIdx()
}
}

suspend fun getIsIntervalTimer(): Boolean {
repository.run {
return getIsIntervalTimer()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.ggaebiz.ggaebiz.domain.usecase

import com.ggaebiz.ggaebiz.domain.repository.TimerRepository

class GetIsRestCompletedUseCase(private val repository: TimerRepository) {
suspend operator fun invoke(): Boolean{
return repository.getIsRestCompleted()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ggaebiz.ggaebiz.domain.usecase

import com.ggaebiz.ggaebiz.domain.repository.TimerRepository

class GetSettingTimerUseCase(private val repository: TimerRepository) {
suspend operator fun invoke(): Pair<Int, Int> {
repository.run {
return Pair(getSettingHour(), getSettingMinute())
}
}
}

This file was deleted.

Loading