Skip to content

Commit

Permalink
Merge pull request #180 from TimerTiTi/release-1.4.0
Browse files Browse the repository at this point in the history
Release 1.4.0
  • Loading branch information
koreatlwls authored Jul 30, 2024
2 parents 09b30a2 + 6f482d0 commit 5cce479
Show file tree
Hide file tree
Showing 13 changed files with 199 additions and 20 deletions.
4 changes: 2 additions & 2 deletions build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ object BuildType {

object AppConfig {
const val APP_ID = "com.titi.app"
const val APP_VERSION_NAME = "1.3.1"
const val APP_VERSION_CODE = 39
const val APP_VERSION_NAME = "1.4.0"
const val APP_VERSION_CODE = 40
const val APP_NAME = "TiTi"
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fun TdsGraphContent(
modifier = Modifier.wrapContentSize(),
userScrollEnabled = true,
state = pagerState,
beyondBoundsPageCount = 2,
beyondBoundsPageCount = 3,
) { page ->
when (page % 4) {
0 -> TdsStandardDailyGraph(
Expand Down
5 changes: 5 additions & 0 deletions core/designsystem/src/main/res/values-ko-rKR/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,9 @@
<string name="recording_text_setnewrecordtitle">새로운 기록 설정</string>
<string name="settings_text_dailyeditcreate">Daily 수정/생성</string>
<string name="edit_text_duplicatehistory">중복된 내역이 존재 합니다.</string>
<string name="setting_text_language">언어</string>
<string name="setting_text_system">시스템</string>
<string name="setting_text_korean">한국어</string>
<string name="setting_text_english">영어</string>
<string name="setting_text_china">중국어</string>
</resources>
5 changes: 5 additions & 0 deletions core/designsystem/src/main/res/values-zh/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,9 @@
<string name="recording_text_setnewrecordtitle">新建日志设置</string>
<string name="settings_text_dailyeditcreate">"每日修改/创建 "</string>
<string name="edit_text_duplicatehistory">重复的历史存在。</string>
<string name="setting_text_language">语言</string>
<string name="setting_text_system">系统</string>
<string name="setting_text_korean">韩国语</string>
<string name="setting_text_english">英语</string>
<string name="setting_text_china">中国话</string>
</resources>
5 changes: 5 additions & 0 deletions core/designsystem/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,9 @@
<string name="recording_text_setnewrecordtitle">Setting New Record</string>
<string name="settings_text_dailyeditcreate">Daily Modify/Create</string>
<string name="edit_text_duplicatehistory">Duplicate history exists.</string>
<string name="setting_text_language">Language</string>
<string name="setting_text_system">System</string>
<string name="setting_text_korean">Korean</string>
<string name="setting_text_english">English</string>
<string name="setting_text_china">Chinese</string>
</resources>
1 change: 1 addition & 0 deletions core/ui/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
plugins {
id("titi.android.compose")
id("titi.android.library")
}

Expand Down
61 changes: 61 additions & 0 deletions core/ui/src/main/kotlin/com/titi/app/core/ui/LanguageManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.titi.app.core.ui

import android.app.LocaleManager
import android.content.Context
import android.os.Build
import android.os.LocaleList
import androidx.core.app.LocaleManagerCompat
import java.util.Locale
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

class LanguageManager(private val context: Context) {
private val _currentLanguage = MutableStateFlow(getCurrentLanguage())
val currentLanguage: StateFlow<String> = _currentLanguage.asStateFlow()

fun setLanguage(languageCode: String) {
val localeList = when (languageCode) {
SYSTEM_DEFAULT -> LocaleList.getEmptyLocaleList()
else -> LocaleList.forLanguageTags(languageCode)
}

_currentLanguage.value = languageCode
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
context.getSystemService(LocaleManager::class.java).applicationLocales = localeList
} else {
val locale = Locale(languageCode)
Locale.setDefault(locale)

val resources = context.resources
val configuration = resources.configuration
configuration.setLocale(locale)
resources.updateConfiguration(configuration, resources.displayMetrics)
}
}

private fun getCurrentLanguage(): String {
return if (isUsingSystemDefault()) {
SYSTEM_DEFAULT
} else {
val currentLocale = context.resources.configuration.locales[0]
when (currentLocale.language) {
"en" -> ENGLISH
"ko" -> KOREAN
"zh" -> CHINA
else -> SYSTEM_DEFAULT
}
}
}

private fun isUsingSystemDefault(): Boolean {
return LocaleManagerCompat.getApplicationLocales(context).isEmpty
}

companion object {
const val SYSTEM_DEFAULT = "system"
const val ENGLISH = "en"
const val KOREAN = "ko"
const val CHINA = "zh"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.titi.app.feature.setting.mapper
import com.titi.app.data.notification.api.model.NotificationRepositoryModel
import com.titi.app.feature.setting.model.SettingUiState

fun SettingUiState.SwitchState.toRepositoryModel() = NotificationRepositoryModel(
internal fun SettingUiState.SwitchState.toRepositoryModel() = NotificationRepositoryModel(
timerFiveMinutesBeforeTheEnd = timerFiveMinutesBeforeTheEnd,
timerBeforeTheEnd = timerBeforeTheEnd,
stopwatch = stopwatch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.titi.app.feature.setting.mapper
import com.titi.app.data.notification.api.model.NotificationRepositoryModel
import com.titi.app.feature.setting.model.SettingUiState

fun NotificationRepositoryModel.toFeatureModel() = SettingUiState.SwitchState(
internal fun NotificationRepositoryModel.toFeatureModel() = SettingUiState.SwitchState(
timerFiveMinutesBeforeTheEnd = timerFiveMinutesBeforeTheEnd,
timerBeforeTheEnd = timerBeforeTheEnd,
stopwatch = stopwatch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ sealed interface SettingActions {
@JvmInline
value class Version(val versionState: SettingUiState.VersionState) : Updates
}

@JvmInline
value class Language(val language: String) : SettingActions
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Switch
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
Expand All @@ -40,6 +42,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel
import com.google.firebase.database.DataSnapshot
Expand All @@ -54,13 +57,14 @@ import com.titi.app.core.designsystem.navigation.TopLevelDestination
import com.titi.app.core.designsystem.theme.TdsColor
import com.titi.app.core.designsystem.theme.TdsTextStyle
import com.titi.app.core.designsystem.theme.TiTiTheme
import com.titi.app.core.ui.LanguageManager
import com.titi.app.feature.setting.model.SettingActions
import com.titi.app.feature.setting.model.SettingUiState
import com.titi.app.feature.setting.model.Version

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingScreen(
internal fun SettingScreen(
viewModel: SettingViewModel = mavericksViewModel(),
handleNavigateActions: (SettingActions.Navigates) -> Unit,
onNavigateToDestination: (TopLevelDestination) -> Unit,
Expand All @@ -71,6 +75,8 @@ fun SettingScreen(
val databaseReference = firebaseDatabase.getReference("versions")

val context = LocalContext.current
val languageManager = remember { LanguageManager(context) }
val currentLanguage by languageManager.currentLanguage.collectAsStateWithLifecycle()

LaunchedEffect(Unit) {
databaseReference.addValueEventListener(
Expand Down Expand Up @@ -142,11 +148,16 @@ fun SettingScreen(
.padding(it)
.safeDrawingPadding(),
uiState = uiState,
currentLanguage = currentLanguage,
onSettingActions = { settingActions ->
when (settingActions) {
is SettingActions.Navigates -> handleNavigateActions(settingActions)

is SettingActions.Updates -> viewModel.handleUpdateActions(settingActions)

is SettingActions.Language -> {
languageManager.setLanguage(settingActions.language)
}
}
},
)
Expand All @@ -157,6 +168,7 @@ fun SettingScreen(
private fun SettingScreen(
modifier: Modifier,
uiState: SettingUiState,
currentLanguage: String,
onSettingActions: (SettingActions) -> Unit,
) {
val scrollState = rememberScrollState()
Expand All @@ -179,6 +191,13 @@ private fun SettingScreen(

Spacer(modifier = Modifier.height(35.dp))

SettingLanguageSection(
currentLanguage = currentLanguage,
onSettingActions = onSettingActions,
)

Spacer(modifier = Modifier.height(35.dp))

SettingVersionSection(
versionState = uiState.versionState,
onSettingActions = onSettingActions,
Expand Down Expand Up @@ -297,6 +316,86 @@ private fun SettingNotificationSection(
)
}

@Composable
private fun SettingLanguageSection(
currentLanguage: String,
onSettingActions: (SettingActions) -> Unit,
) {
TdsText(
modifier = Modifier.padding(start = 16.dp),
text = stringResource(R.string.setting_text_language),
textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE,
fontSize = 14.sp,
color = TdsColor.TEXT,
)

Spacer(modifier = Modifier.height(4.dp))

ListContent(
title = stringResource(R.string.setting_text_system),
rightAreaContent = {
RadioButton(
selected = currentLanguage == LanguageManager.SYSTEM_DEFAULT,
onClick = {
onSettingActions(
SettingActions.Language(LanguageManager.SYSTEM_DEFAULT),
)
},
)
},
)

Spacer(modifier = Modifier.height(1.dp))

ListContent(
title = stringResource(R.string.setting_text_korean),
rightAreaContent = {
RadioButton(
selected = currentLanguage == LanguageManager.KOREAN,
onClick = {
onSettingActions(
SettingActions.Language(LanguageManager.KOREAN),
)
},
)
},
)

Spacer(modifier = Modifier.height(1.dp))

ListContent(
title = stringResource(R.string.setting_text_english),
rightAreaContent = {
RadioButton(
selected = currentLanguage == LanguageManager.ENGLISH,
onClick = {
onSettingActions(
SettingActions.Language(LanguageManager.ENGLISH),
)
},
)
},
)

Spacer(modifier = Modifier.height(1.dp))

ListContent(
title = stringResource(R.string.setting_text_china),
rightAreaContent = {
RadioButton(
selected = currentLanguage == LanguageManager.CHINA,
onClick = {
onSettingActions(
SettingActions.Language(LanguageManager.CHINA),
)
},
)
},
)

Spacer(modifier = Modifier.height(1.dp))
}

@Composable
private fun SettingVersionSection(
versionState: SettingUiState.VersionState,
Expand Down Expand Up @@ -500,6 +599,7 @@ private fun SettingScreenPreview() {
SettingScreen(
modifier = Modifier,
uiState = SettingUiState(),
currentLanguage = LanguageManager.SYSTEM_DEFAULT,
onSettingActions = {},
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.titi.app.feature.setting.ui

import android.util.Log
import com.airbnb.mvrx.MavericksViewModel
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.hilt.AssistedViewModelFactory
Expand All @@ -12,39 +13,36 @@ import com.titi.app.feature.setting.model.SettingUiState
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.launch

class SettingViewModel @AssistedInject constructor(
internal class SettingViewModel @AssistedInject constructor(
@Assisted initialState: SettingUiState,
private val notificationRepository: NotificationRepository,
) : MavericksViewModel<SettingUiState>(initialState) {

init {
viewModelScope.launch {
notificationRepository.getNotificationFlow()
.collectLatest {
updateSwitch(it.toFeatureModel())
.catch {
Log.e("SettingViewModel", it.message.toString())
}.setOnEach {
copy(switchState = it.toFeatureModel())
}
}
}

fun handleUpdateActions(updateActions: SettingActions.Updates) {
when (updateActions) {
is SettingActions.Updates.Switch -> {
viewModelScope.launch {
notificationRepository
.setNotification(updateActions.switchState.toRepositoryModel())
}
}
is SettingActions.Updates.Switch -> updateSwitch(updateActions.switchState)

is SettingActions.Updates.Version -> updateVersion(updateActions.versionState)
}
}

private fun updateSwitch(switchState: SettingUiState.SwitchState) {
setState {
copy(switchState = switchState)
viewModelScope.launch {
notificationRepository.setNotification(switchState.toRepositoryModel())
}
}

Expand Down
5 changes: 3 additions & 2 deletions release-note.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
TiTi android dev 1.3.1
-
TiTi android 1.4.0
- Setting Screen Ver.3
- Bug share picture

0 comments on commit 5cce479

Please sign in to comment.