l18n added
This commit is contained in:
31
GEMINI.md
31
GEMINI.md
@@ -61,6 +61,37 @@
|
|||||||
<Phase id="3" name="OptimizationAndRefactoring">Рефакторинг с сохранением всех контрактных гарантий.</Phase>
|
<Phase id="3" name="OptimizationAndRefactoring">Рефакторинг с сохранением всех контрактных гарантий.</Phase>
|
||||||
</Principle>
|
</Principle>
|
||||||
</GuidingPrinciples>
|
</GuidingPrinciples>
|
||||||
|
<BuildAndCompilationPrinciples>
|
||||||
|
<Description>Принципы для обеспечения компилируемости и совместимости генерируемого кода в Android/Gradle/Kotlin проектах.</Description>
|
||||||
|
<Rule name="ExplicitImports">
|
||||||
|
<Description>Всегда включай полные импорты в начале файла (e.g., import androidx.navigation.NavGraph). Проверяй на unresolved references перед финальной генерацией.</Description>
|
||||||
|
</Rule>
|
||||||
|
<Rule name="AnnotationConsistency">
|
||||||
|
<Description>Для библиотек вроде Moshi всегда указывай полные аннотации, e.g., @JsonClass(generateAdapter = true). Избегай ошибок missing default value.</Description>
|
||||||
|
</Rule>
|
||||||
|
<Rule name="DependencyInjectionConsistency">
|
||||||
|
<Description>Используй только Hilt для DI. Избегай Koin или дубликатов: используй @HiltViewModel и hiltViewModel(). При генерации проверяй на конфликты.</Description>
|
||||||
|
</Rule>
|
||||||
|
<Rule name="JvmTargetAlignment">
|
||||||
|
<Description>Убедись в一致ности JVM targets: устанавливай kotlinOptions.jvmTarget = "21" и javaToolchain.languageVersion = JavaLanguageVersion.of(21) в build.gradle.kts. Проверяй на inconsistent compatibility errors.</Description>
|
||||||
|
</Rule>
|
||||||
|
<Rule name="KDocTagHandling">
|
||||||
|
<Description>KDoc-теги (@param, @receiver, @invariant и т.д.) — это метаданные, не пути к файлам. Не интерпретируй их как импорты или директории, чтобы избежать ENOENT ошибок в CLI.</Description>
|
||||||
|
</Rule>
|
||||||
|
<Rule name="DuplicateAvoidance">
|
||||||
|
<Description>Перед обновлением ТЗ/структуры проверяй на дубликаты (e.g., logging в TECHNICAL_DECISIONS). Если дубли — объединяй. Для SECURITY_SPEC избегай повторений с ERROR_HANDLING.</Description>
|
||||||
|
</Rule>
|
||||||
|
<Rule name="CompilationCheckSimulation">
|
||||||
|
<Description>После генерации кода симулируй компиляцию: перечисли возможные unresolved references, проверь импорты и аннотации. Если ошибки — итеративно исправляй до coherence.</Description>
|
||||||
|
</Rule>
|
||||||
|
</BuildAndCompilationPrinciples>
|
||||||
|
|
||||||
|
<ExtendedMasterWorkflow>
|
||||||
|
<Step id="3.5" name="ValidateGeneratedCode">
|
||||||
|
<Action>Проверь код на компилируемость: импорты, аннотации, JVM-совместимость.</Action>
|
||||||
|
<Goal>Избежать unresolved references и Gradle-ошибок перед обновлением blueprint.</Goal>
|
||||||
|
</Step>
|
||||||
|
</ExtendedMasterWorkflow>
|
||||||
|
|
||||||
<AntiPatterns phase="initial_generation">
|
<AntiPatterns phase="initial_generation">
|
||||||
<Description>Традиционные "Best Practices" как потенциальные анти-паттерны на этапе начальной генерации (Фаза 1).</Description>
|
<Description>Традиционные "Best Practices" как потенциальные анти-паттерны на этапе начальной генерации (Фаза 1).</Description>
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ private fun LocationsSection(locations: List<LocationOutCount>, onLocationClick:
|
|||||||
locations.forEach { location ->
|
locations.forEach { location ->
|
||||||
SuggestionChip(
|
SuggestionChip(
|
||||||
onClick = { onLocationClick(location) },
|
onClick = { onLocationClick(location) },
|
||||||
label = { Text("${location.name} (${location.itemCount})") }
|
label = { Text(stringResource(id = R.string.location_chip_label, location.name, location.itemCount)) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import com.homebox.lens.R
|
||||||
|
|
||||||
// [FIX] Opt-in for experimental Material 3 APIs
|
// [FIX] Opt-in for experimental Material 3 APIs
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@@ -52,7 +52,7 @@ private fun SetupScreenContent(
|
|||||||
) {
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(title = { Text("Server Setup") })
|
TopAppBar(title = { Text(stringResource(id = R.string.setup_title)) })
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
Column(
|
Column(
|
||||||
@@ -66,21 +66,21 @@ private fun SetupScreenContent(
|
|||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = uiState.serverUrl,
|
value = uiState.serverUrl,
|
||||||
onValueChange = onServerUrlChange,
|
onValueChange = onServerUrlChange,
|
||||||
label = { Text("Server URL") },
|
label = { Text(stringResource(id = R.string.setup_server_url_label)) },
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = uiState.username,
|
value = uiState.username,
|
||||||
onValueChange = onUsernameChange,
|
onValueChange = onUsernameChange,
|
||||||
label = { Text("Username") },
|
label = { Text(stringResource(id = R.string.setup_username_label)) },
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = uiState.password,
|
value = uiState.password,
|
||||||
onValueChange = onPasswordChange,
|
onValueChange = onPasswordChange,
|
||||||
label = { Text("Password") },
|
label = { Text(stringResource(id = R.string.setup_password_label)) },
|
||||||
visualTransformation = PasswordVisualTransformation(),
|
visualTransformation = PasswordVisualTransformation(),
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
@@ -93,7 +93,7 @@ private fun SetupScreenContent(
|
|||||||
if (uiState.isLoading) {
|
if (uiState.isLoading) {
|
||||||
CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
||||||
} else {
|
} else {
|
||||||
Text("Connect")
|
Text(stringResource(id = R.string.setup_connect_button))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uiState.error?.let {
|
uiState.error?.let {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
<string name="dashboard_section_recently_added">Recently Added</string>
|
<string name="dashboard_section_recently_added">Recently Added</string>
|
||||||
<string name="dashboard_section_locations">Locations</string>
|
<string name="dashboard_section_locations">Locations</string>
|
||||||
<string name="dashboard_section_labels">Labels</string>
|
<string name="dashboard_section_labels">Labels</string>
|
||||||
|
<string name="location_chip_label">%1$s (%2$d)</string>
|
||||||
|
|
||||||
<!-- Dashboard Statistics -->
|
<!-- Dashboard Statistics -->
|
||||||
<string name="dashboard_stat_total_items">Total Items</string>
|
<string name="dashboard_stat_total_items">Total Items</string>
|
||||||
@@ -33,4 +34,11 @@
|
|||||||
<string name="nav_locations">Locations</string>
|
<string name="nav_locations">Locations</string>
|
||||||
<string name="nav_labels">Labels</string>
|
<string name="nav_labels">Labels</string>
|
||||||
|
|
||||||
|
<!-- Setup Screen -->
|
||||||
|
<string name="setup_title">Server Setup</string>
|
||||||
|
<string name="setup_server_url_label">Server URL</string>
|
||||||
|
<string name="setup_username_label">Username</string>
|
||||||
|
<string name="setup_password_label">Password</string>
|
||||||
|
<string name="setup_connect_button">Connect</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
<string name="dashboard_section_recently_added">Недавно добавлено</string>
|
<string name="dashboard_section_recently_added">Недавно добавлено</string>
|
||||||
<string name="dashboard_section_locations">Места хранения</string>
|
<string name="dashboard_section_locations">Места хранения</string>
|
||||||
<string name="dashboard_section_labels">Метки</string>
|
<string name="dashboard_section_labels">Метки</string>
|
||||||
|
<string name="location_chip_label">%1$s (%2$d)</string>
|
||||||
|
|
||||||
<!-- Dashboard Statistics -->
|
<!-- Dashboard Statistics -->
|
||||||
<string name="dashboard_stat_total_items">Всего вещей</string>
|
<string name="dashboard_stat_total_items">Всего вещей</string>
|
||||||
@@ -33,4 +34,11 @@
|
|||||||
<string name="nav_locations">Локации</string>
|
<string name="nav_locations">Локации</string>
|
||||||
<string name="nav_labels">Метки</string>
|
<string name="nav_labels">Метки</string>
|
||||||
|
|
||||||
|
<!-- Setup Screen -->
|
||||||
|
<string name="setup_title">Настройка сервера</string>
|
||||||
|
<string name="setup_server_url_label">URL сервера</string>
|
||||||
|
<string name="setup_username_label">Имя пользователя</string>
|
||||||
|
<string name="setup_password_label">Пароль</string>
|
||||||
|
<string name="setup_connect_button">Подключиться</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<summary>Библиотека логирования</summary>
|
<summary>Библиотека логирования</summary>
|
||||||
<description>В проекте используется Timber (timber.log.Timber) для всех целей логирования. Он предоставляет простой и расширяемый API для логирования.</description>
|
<description>В проекте используется Timber (timber.log.Timber) для всех целей логирования. Он предоставляет простой и расширяемый API для логирования.</description>
|
||||||
</DECISION>
|
</DECISION>
|
||||||
<DECISION id="tech_i18n" status="defined">
|
<DECISION id="tech_i18n" status="implemented">
|
||||||
<summary>Интернационализация (Мультиязычность)</summary>
|
<summary>Интернационализация (Мультиязычность)</summary>
|
||||||
<description>
|
<description>
|
||||||
Приложение должно поддерживать несколько языков для обеспечения доступности для глобальной аудитории.
|
Приложение должно поддерживать несколько языков для обеспечения доступности для глобальной аудитории.
|
||||||
|
|||||||
Reference in New Issue
Block a user