211
This commit is contained in:
199
tasks/completed/current_work_order.xml
Normal file
199
tasks/completed/current_work_order.xml
Normal file
@@ -0,0 +1,199 @@
|
||||
<WORK_ORDER feature="Settings Screen">
|
||||
<ACTION type="MODIFY" file_path="./app/src/main/java/com/homebox/lens/navigation/Screen.kt">
|
||||
<DESCRIPTION>Добавить маршрут для экрана настроек в sealed class Screen.</DESCRIPTION>
|
||||
<INSERT after="// [END_ENTITY: Object('Search')]">
|
||||
<![CDATA[
|
||||
|
||||
// [ENTITY: Object('Settings')]
|
||||
data object Settings : Screen("settings_screen")
|
||||
// [END_ENTITY: Object('Settings')]
|
||||
]]>
|
||||
</INSERT>
|
||||
</ACTION>
|
||||
|
||||
<ACTION type="CREATE" file_path="./app/src/main/java/com/homebox/lens/ui/screen/settings/SettingsUiState.kt">
|
||||
<DESCRIPTION>Создать data class для состояния UI экрана настроек.</DESCRIPTION>
|
||||
<CONTENT>
|
||||
<![CDATA[
|
||||
package com.homebox.lens.ui.screen.settings
|
||||
|
||||
data class SettingsUiState(
|
||||
val serverUrl: String = "",
|
||||
val isLoading: Boolean = false,
|
||||
val error: String? = null,
|
||||
val isSaved: Boolean = false
|
||||
)
|
||||
]]>
|
||||
</CONTENT>
|
||||
</ACTION>
|
||||
|
||||
<ACTION type="CREATE" file_path="./app/src/main/java/com/homebox/lens/ui/screen/settings/SettingsViewModel.kt">
|
||||
<DESCRIPTION>Создать ViewModel для экрана настроек.</DESCRIPTION>
|
||||
<CONTENT>
|
||||
<![CDATA[
|
||||
package com.homebox.lens.ui.screen.settings
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.homebox.lens.domain.repository.CredentialsRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class SettingsViewModel @Inject constructor(
|
||||
private val credentialsRepository: CredentialsRepository
|
||||
) : ViewModel() {
|
||||
|
||||
private val _uiState = MutableStateFlow(SettingsUiState())
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
init {
|
||||
loadCurrentSettings()
|
||||
}
|
||||
|
||||
private fun loadCurrentSettings() {
|
||||
viewModelScope.launch {
|
||||
_uiState.value = _uiState.value.copy(isLoading = true)
|
||||
val credentials = credentialsRepository.getCredentials().first()
|
||||
_uiState.value = _uiState.value.copy(
|
||||
serverUrl = credentials?.serverUrl ?: "",
|
||||
isLoading = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun onServerUrlChange(newUrl: String) {
|
||||
_uiState.value = _uiState.value.copy(serverUrl = newUrl, isSaved = false)
|
||||
}
|
||||
|
||||
fun saveSettings() {
|
||||
// TODO: Implement saving logic, probably need a use case
|
||||
// For now, just simulate success
|
||||
viewModelScope.launch {
|
||||
_uiState.value = _uiState.value.copy(isLoading = true)
|
||||
// val success = saveSettingsUseCase(_uiState.value.serverUrl)
|
||||
_uiState.value = _uiState.value.copy(isLoading = false, isSaved = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</CONTENT>
|
||||
</ACTION>
|
||||
|
||||
<ACTION type="CREATE" file_path="./app/src/main/java/com/homebox/lens/ui/screen/settings/SettingsScreen.kt">
|
||||
<DESCRIPTION>Создать Composable для UI экрана настроек.</DESCRIPTION>
|
||||
<CONTENT>
|
||||
<![CDATA[
|
||||
package com.homebox.lens.ui.screen.settings
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.homebox.lens.navigation.Screen
|
||||
import com.homebox.lens.ui.common.MainScaffold
|
||||
|
||||
@Composable
|
||||
fun SettingsScreen(
|
||||
viewModel: SettingsViewModel = hiltViewModel(),
|
||||
onNavigateUp: () -> Unit
|
||||
) {
|
||||
val uiState by viewModel.uiState.collectAsState()
|
||||
|
||||
MainScaffold(
|
||||
title = "Настройки",
|
||||
onNavigateUp = onNavigateUp
|
||||
) { paddingValues ->
|
||||
SettingsContent(
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
uiState = uiState,
|
||||
onServerUrlChange = viewModel::onServerUrlChange,
|
||||
onSaveClick = viewModel::saveSettings
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SettingsContent(
|
||||
modifier: Modifier = Modifier,
|
||||
uiState: SettingsUiState,
|
||||
onServerUrlChange: (String) -> Unit,
|
||||
onSaveClick: () -> Unit
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = uiState.serverUrl,
|
||||
onValueChange = onServerUrlChange,
|
||||
label = { Text("URL Сервера") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Button(
|
||||
onClick = onSaveClick,
|
||||
enabled = !uiState.isLoading,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
if (uiState.isLoading) {
|
||||
CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
||||
} else {
|
||||
Text("Сохранить")
|
||||
}
|
||||
}
|
||||
if (uiState.isSaved) {
|
||||
Text("Настройки сохранены!", color = MaterialTheme.colorScheme.primary)
|
||||
}
|
||||
if (uiState.error != null) {
|
||||
Text(uiState.error, color = MaterialTheme.colorScheme.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</CONTENT>
|
||||
</ACTION>
|
||||
|
||||
<ACTION type="MODIFY" file_path="./app/src/main/java/com/homebox/lens/navigation/NavGraph.kt">
|
||||
<DESCRIPTION>Добавить экран настроек в навигационный граф.</DESCRIPTION>
|
||||
<INSERT after='composable(Screen.Search.route) { SearchScreen(navActions) }'>
|
||||
<![CDATA[
|
||||
composable(Screen.Settings.route) {
|
||||
SettingsScreen(
|
||||
onNavigateUp = { navActions.navController.navigateUp() }
|
||||
)
|
||||
}
|
||||
]]>
|
||||
</INSERT>
|
||||
</ACTION>
|
||||
|
||||
<ACTION type="MODIFY" file_path="./app/src/main/java/com/homebox/lens/ui/common/AppDrawer.kt">
|
||||
<DESCRIPTION>Добавить пункт "Настройки" в боковое меню.</DESCRIPTION>
|
||||
<INSERT after=' onClick = {
|
||||
navActions.navController.navigate(Screen.LocationsList.route)
|
||||
scope.launch { drawerState.close() }
|
||||
}
|
||||
)'>
|
||||
<![CDATA[
|
||||
NavigationDrawerItem(
|
||||
icon = { Icon(Icons.Default.Settings, contentDescription = null) },
|
||||
label = { Text("Настройки") },
|
||||
selected = false,
|
||||
onClick = {
|
||||
navActions.navController.navigate(Screen.Settings.route)
|
||||
scope.launch { drawerState.close() }
|
||||
}
|
||||
)
|
||||
]]>
|
||||
</INSERT>
|
||||
</ACTION>
|
||||
</WORK_ORDER>
|
||||
Reference in New Issue
Block a user