feat: app-level display name (v0.3.1)

This commit is contained in:
tkrmagid
2026-08-05 14:45:57 +09:00
parent 39a4543640
commit 2287e1cf83
7 changed files with 34 additions and 4 deletions

View File

@@ -17,6 +17,8 @@ private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(na
/** User/admin choices that must survive app restarts. */
data class AppSettings(
/** App-level display name shown as the home header; null = default. */
val appName: String? = null,
val selectedDeviceId: String? = null,
val showRemainingTime: Boolean = true,
val showReservation: Boolean = true,
@@ -36,6 +38,7 @@ class SettingsRepository(private val context: Context) {
val settings: Flow<AppSettings> = context.dataStore.data.map { p ->
AppSettings(
appName = p[KEY_APP_NAME]?.takeIf { it.isNotBlank() },
selectedDeviceId = p[KEY_SELECTED_DEVICE],
showRemainingTime = p[KEY_SHOW_REMAINING] ?: true,
showReservation = p[KEY_SHOW_RESERVATION] ?: true,
@@ -47,6 +50,9 @@ class SettingsRepository(private val context: Context) {
)
}
suspend fun setAppName(name: String) =
edit { it[KEY_APP_NAME] = name.trim() }
suspend fun setSelectedDevice(deviceId: String) =
edit { it[KEY_SELECTED_DEVICE] = deviceId }
@@ -93,6 +99,7 @@ class SettingsRepository(private val context: Context) {
else runCatching { Json.decodeFromString<Map<String, DeviceMacro>>(raw) }.getOrDefault(emptyMap())
private companion object {
val KEY_APP_NAME = stringPreferencesKey("app_name")
val KEY_SELECTED_DEVICE = stringPreferencesKey("selected_device_id")
val KEY_SHOW_REMAINING = booleanPreferencesKey("show_remaining_time")
val KEY_SHOW_RESERVATION = booleanPreferencesKey("show_reservation")

View File

@@ -49,6 +49,7 @@ import kr.tkrmagid.easyappliance.data.DeviceImages
import kr.tkrmagid.easyappliance.data.DeviceMacro
import kr.tkrmagid.easyappliance.data.ImageStorage
import kr.tkrmagid.easyappliance.vm.HomeUiState
import kr.tkrmagid.easyappliance.vm.appDisplayName
import kr.tkrmagid.easyappliance.vm.displayLabelFor
import kr.tkrmagid.easyappliance.vm.imageRefFor
import kr.tkrmagid.easyappliance.vm.macroFor
@@ -57,6 +58,7 @@ import kr.tkrmagid.easyappliance.vm.macroFor
fun AdminScreen(
state: HomeUiState,
onSelectDevice: (String) -> Unit,
onSetAppName: (String) -> Unit,
onToggleRemaining: (Boolean) -> Unit,
onToggleReservation: (Boolean) -> Unit,
onTogglePowerControls: (Boolean) -> Unit,
@@ -78,6 +80,13 @@ fun AdminScreen(
Text("관리자 설정", style = MaterialTheme.typography.headlineLarge)
Spacer(Modifier.height(24.dp))
SectionTitle("앱 이름 바꾸기")
NameEditor(
current = state.appDisplayName(),
onSave = onSetAppName,
)
Spacer(Modifier.height(28.dp))
SectionTitle("조작할 기기 선택")
Card(
modifier = Modifier.fillMaxWidth(),
@@ -104,7 +113,7 @@ fun AdminScreen(
if (selected != null) {
Spacer(Modifier.height(28.dp))
SectionTitle("이름 바꾸기")
SectionTitle("기기 이름 바꾸기")
NameEditor(
current = state.displayLabelFor(selected),
onSave = { onSetLabel(selected.id, it) },

View File

@@ -63,6 +63,7 @@ fun AppRoot() {
Screen.ADMIN -> AdminScreen(
state = state,
onSelectDevice = vm::selectDevice,
onSetAppName = vm::setAppName,
onToggleRemaining = vm::setShowRemainingTime,
onToggleReservation = vm::setShowReservation,
onTogglePowerControls = vm::setShowPowerControls,

View File

@@ -34,6 +34,7 @@ import androidx.compose.ui.unit.dp
import kr.tkrmagid.easyappliance.data.DeviceType
import androidx.compose.material.icons.filled.PlayArrow
import kr.tkrmagid.easyappliance.vm.HomeUiState
import kr.tkrmagid.easyappliance.vm.appDisplayName
import kr.tkrmagid.easyappliance.vm.displayLabelFor
import kr.tkrmagid.easyappliance.vm.imageRefFor
import kr.tkrmagid.easyappliance.vm.macroFor
@@ -71,6 +72,13 @@ fun HomeScreen(
modifier = Modifier.widthIn(max = contentMaxWidth).fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = state.appDisplayName(),
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.primary,
textAlign = TextAlign.Center,
)
Spacer(Modifier.height(16.dp))
DeviceImage(
imageRef = state.imageRefFor(device),
modifier = Modifier.size(if (narrow) 96.dp else 128.dp),

View File

@@ -170,6 +170,7 @@ class AppViewModel(app: Application) : AndroidViewModel(app) {
viewModelScope.launch { settingsRepo.setDeviceMacro(deviceId, macro) }
}
fun setAppName(name: String) { viewModelScope.launch { settingsRepo.setAppName(name) } }
fun setShowRemainingTime(value: Boolean) { viewModelScope.launch { settingsRepo.setShowRemainingTime(value) } }
fun setShowReservation(value: Boolean) { viewModelScope.launch { settingsRepo.setShowReservation(value) } }
fun setShowPowerControls(value: Boolean) { viewModelScope.launch { settingsRepo.setShowPowerControls(value) } }
@@ -188,3 +189,8 @@ fun HomeUiState.imageRefFor(device: Device): String =
/** The device's macro, or null if none configured. */
fun HomeUiState.macroFor(device: Device): DeviceMacro? = settings.deviceMacros[device.id]
const val DEFAULT_APP_NAME = "쉬운 가전 리모컨"
/** App-level display name shown as the home header. */
fun HomeUiState.appDisplayName(): String = settings.appName ?: DEFAULT_APP_NAME