-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Remote Config 기반 앱 테마 전환 추가 #516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
5a00644
3dfed08
a86b722
a2f76a0
39cb2e5
55387d0
f429dcb
f8ec64f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| package com.eatssu.android.data.local | ||
|
|
||
| import android.content.Context | ||
| import androidx.datastore.core.DataStore | ||
| import androidx.datastore.preferences.core.Preferences | ||
| import androidx.datastore.preferences.core.edit | ||
| import androidx.datastore.preferences.core.stringPreferencesKey | ||
| import androidx.datastore.preferences.preferencesDataStore | ||
| import com.eatssu.android.domain.model.AppTheme | ||
| import dagger.hilt.android.qualifiers.ApplicationContext | ||
| import kotlinx.coroutines.flow.Flow | ||
| import kotlinx.coroutines.flow.map | ||
| import kotlinx.coroutines.flow.distinctUntilChanged | ||
| import kotlinx.coroutines.flow.first | ||
| import kotlinx.coroutines.runBlocking | ||
| import javax.inject.Inject | ||
| import javax.inject.Singleton | ||
|
|
||
| private val Context.appThemeDataStore: DataStore<Preferences> by preferencesDataStore(name = "app_theme") | ||
|
|
||
| @Singleton | ||
| class AppThemeDataStore @Inject constructor( | ||
| @ApplicationContext private val context: Context, | ||
| ) { | ||
|
|
||
| companion object { | ||
| private val APP_THEME_KEY = stringPreferencesKey("app_theme") | ||
| } | ||
|
|
||
| val appTheme: Flow<AppTheme> = context.appThemeDataStore.data | ||
| .map { preferences -> | ||
| AppTheme.fromStringOrDefault(preferences[APP_THEME_KEY].orEmpty()) | ||
| } | ||
| .distinctUntilChanged() | ||
|
|
||
| val cachedAppTheme: AppTheme by lazy(LazyThreadSafetyMode.NONE) { | ||
| runBlocking { appTheme.first() } | ||
| } | ||
|
PeraSite marked this conversation as resolved.
Outdated
|
||
|
|
||
| suspend fun setAppTheme(theme: AppTheme) { | ||
| context.appThemeDataStore.edit { preferences -> | ||
| preferences[APP_THEME_KEY] = theme.remoteValue | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| package com.eatssu.android.data.remote.repository | ||
|
|
||
| import com.eatssu.android.R | ||
| import com.eatssu.android.domain.model.AppTheme | ||
| import com.eatssu.android.domain.model.RestaurantInfo | ||
| import com.eatssu.android.domain.repository.FirebaseRemoteConfigRepository | ||
| import com.eatssu.common.enums.Restaurant | ||
|
|
@@ -29,25 +30,27 @@ class FirebaseRemoteConfigRepositoryImpl @Inject constructor( | |
| } | ||
|
|
||
| override suspend fun getMinimumVersionCode(): Long { | ||
| // 값을 가져오기 전에 fetchAndActivate 호출 | ||
| // min fetch interval이 지나지 않았으면 로컬 캐시를 사용하고, 지났으면 서버에서 가져옵니다. | ||
| try { | ||
| instance.fetchAndActivate().await() | ||
| } catch (e: Exception) { | ||
| Timber.e(e, "RemoteConfig fetchAndActivate 실패") | ||
| } | ||
| fetchAndActivateSafely() | ||
| return instance.getLong("android_version_code") | ||
| } | ||
|
|
||
| override suspend fun getAppTheme(): AppTheme { | ||
| fetchAndActivateSafely() | ||
| return AppTheme.fromStringOrDefault(instance.getString("app_theme")) | ||
| } | ||
|
|
||
| override suspend fun getRestaurantInfo(restaurant: Restaurant): RestaurantInfo? { | ||
| // 값을 가져오기 전에 fetchAndActivate 호출 | ||
| fetchAndActivateSafely() | ||
| return getCafeteriaInfo().find { it.enum == restaurant } | ||
|
Comment on lines
32
to
+44
|
||
| } | ||
|
|
||
| private suspend fun fetchAndActivateSafely() { | ||
| // min fetch interval이 지나지 않았으면 로컬 캐시를 사용하고, 지났으면 서버에서 가져옵니다. | ||
| try { | ||
| instance.fetchAndActivate().await() | ||
| } catch (e: Exception) { | ||
| Timber.e(e, "RemoteConfig fetchAndActivate 실패") | ||
| } | ||
| return getCafeteriaInfo().find { it.enum == restaurant } | ||
| } | ||
|
|
||
| private fun getCafeteriaInfo(): List<RestaurantInfo> { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package com.eatssu.android.domain.model | ||
|
|
||
| import androidx.annotation.AnyRes | ||
| import androidx.annotation.DrawableRes | ||
| import com.eatssu.android.R | ||
|
|
||
| enum class AppTheme( | ||
| val remoteValue: String, | ||
| @AnyRes val splashBackgroundResId: Int, | ||
| @DrawableRes val splashLogoResId: Int, | ||
| val launcherAliasSuffix: String, | ||
| ) { | ||
| DEFAULT( | ||
| remoteValue = "default", | ||
| splashBackgroundResId = R.color.primary, | ||
| splashLogoResId = R.drawable.img_logo, | ||
| launcherAliasSuffix = ".alias.DefaultLauncherAlias", | ||
| ), | ||
| CHRISTMAS( | ||
| remoteValue = "christmas", | ||
| splashBackgroundResId = R.drawable.img_background_snow, | ||
| splashLogoResId = R.drawable.img_logo_snow, | ||
| launcherAliasSuffix = ".alias.ChristmasLauncherAlias", | ||
| ), | ||
| SPRING( | ||
| remoteValue = "spring", | ||
| splashBackgroundResId = R.drawable.img_background_spring, | ||
| splashLogoResId = R.drawable.img_logo, | ||
| launcherAliasSuffix = ".alias.SpringLauncherAlias", | ||
| ); | ||
|
|
||
| companion object { | ||
| fun fromStringOrDefault(value: String): AppTheme { | ||
| return entries.find { it.remoteValue.equals(value, ignoreCase = true) } ?: DEFAULT | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <background android:drawable="@color/white"/> | ||
| <foreground android:drawable="@mipmap/ic_launcher_spring_foreground"/> | ||
| </adaptive-icon> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <background android:drawable="@color/white"/> | ||
| <foreground android:drawable="@mipmap/ic_launcher_spring_foreground"/> | ||
| </adaptive-icon> |
Uh oh!
There was an error while loading. Please reload this page.