fix: remove legacy text icons and placeholders

This commit is contained in:
2026-08-26 21:14:09 +08:00
parent 7a107cc55a
commit d8d9eb4f28
12 changed files with 173 additions and 159 deletions
@@ -57,6 +57,7 @@ dependencies {
implementation(libs.compose.ui)
implementation(libs.compose.ui.tooling.preview)
implementation(libs.compose.material3)
implementation(libs.compose.material.icons.extended)
testImplementation(libs.junit)
testImplementation(libs.kotlinx.coroutines.test)
@@ -271,10 +271,10 @@ private fun VirtualRemoteCard(
verticalAlignment = Alignment.CenterVertically,
) {
val icon = when (remote.type) {
RemoteDeviceType.TV -> "📺"
RemoteDeviceType.AIR_CONDITIONER -> "❄️"
RemoteDeviceType.TV -> "电视"
RemoteDeviceType.AIR_CONDITIONER -> "空调"
RemoteDeviceType.FAN -> "🌀"
RemoteDeviceType.CUSTOM -> "🎛️"
RemoteDeviceType.CUSTOM -> "自定义"
}
Text(icon, fontSize = 28.sp)
IconButton(onClick = onDelete, modifier = Modifier.testTag("delete_remote_${remote.id.value}")) {
@@ -288,11 +288,11 @@ private fun VirtualRemoteCard(
)
val modeText = if (remote.type == RemoteDeviceType.AIR_CONDITIONER) {
"❄️ 状态机动态写码"
"状态机动态写码"
} else if (remote.transmissionMode == TransmissionMode.STATIC_SLOTS) {
"🚀 静态独占槽位"
"静态独占槽位"
} else {
"📦 动态写码"
"动态写码"
}
Text(
@@ -430,7 +430,7 @@ private fun CreateVirtualRemoteDialog(
OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("遥控器名称(如:客厅电视、我的遥控器)") },
label = { Text("遥控器名称(如:电视、我的遥控器)") },
singleLine = true,
modifier = Modifier.fillMaxWidth().testTag("create_remote_name_input"),
)
@@ -443,10 +443,10 @@ private fun CreateVirtualRemoteDialog(
) {
OutlinedTextField(
value = when (selectedCustomLayout) {
PanelLayoutStyle.TV_NAV -> "📺 电视导航布局 (内置方向盘/音量/频道)"
PanelLayoutStyle.MEDIA_PLAYER -> "🎵 媒体播放器布局 (播放/快进/切歌)"
PanelLayoutStyle.GRID -> "🎛️ 自由网格布局 (可自由增删按键)"
PanelLayoutStyle.AC_COMPACT -> "❄️ 空调布局"
PanelLayoutStyle.TV_NAV -> "电视导航布局(内置方向盘、音量、频道)"
PanelLayoutStyle.MEDIA_PLAYER -> "媒体播放器布局(播放、快进、切歌)"
PanelLayoutStyle.GRID -> "自由网格布局(可自由增删按键)"
PanelLayoutStyle.AC_COMPACT -> "空调布局"
},
onValueChange = {},
readOnly = true,
@@ -459,21 +459,21 @@ private fun CreateVirtualRemoteDialog(
onDismissRequest = { layoutDropdownExpanded = false },
) {
DropdownMenuItem(
text = { Text("📺 电视导航布局 (内置方向盘/音量/频道)") },
text = { Text("电视导航布局(内置方向盘、音量、频道)") },
onClick = {
selectedCustomLayout = PanelLayoutStyle.TV_NAV
layoutDropdownExpanded = false
},
)
DropdownMenuItem(
text = { Text("🎵 媒体播放器布局 (播放/快进/切歌)") },
text = { Text("媒体播放器布局(播放、快进、切歌)") },
onClick = {
selectedCustomLayout = PanelLayoutStyle.MEDIA_PLAYER
layoutDropdownExpanded = false
},
)
DropdownMenuItem(
text = { Text("🎛️ 自由网格布局 (可自由增删按键)") },
text = { Text("自由网格布局(可自由增删按键)") },
onClick = {
selectedCustomLayout = PanelLayoutStyle.GRID
layoutDropdownExpanded = false
@@ -538,7 +538,7 @@ private fun CreateVirtualRemoteDialog(
onClick = { transmissionMode = TransmissionMode.STATIC_SLOTS },
)
Column {
Text("🚀 静态独占槽位模式", fontWeight = FontWeight.Medium)
Text("静态独占槽位模式", fontWeight = FontWeight.Medium)
Text(stringResource(R.string.infrared_hub_trans_mode_static_desc), fontSize = 11.sp, color = MaterialTheme.colorScheme.onSurfaceVariant)
}
}
@@ -552,7 +552,7 @@ private fun CreateVirtualRemoteDialog(
onClick = { transmissionMode = TransmissionMode.DYNAMIC_SCRATCH },
)
Column {
Text("📦 动态写码模式", fontWeight = FontWeight.Medium)
Text("动态写码模式", fontWeight = FontWeight.Medium)
Text(stringResource(R.string.infrared_hub_trans_mode_dynamic_desc), fontSize = 11.sp, color = MaterialTheme.colorScheme.onSurfaceVariant)
}
}
@@ -563,7 +563,7 @@ private fun CreateVirtualRemoteDialog(
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = "❄️ 空调多维状态自动采用 App 状态机 + 动态缓冲写码,杜绝状态踩踏并节省槽位。",
text = "空调多维状态自动采用状态机和动态缓冲写码,避免状态冲突并节省槽位。",
fontSize = 12.sp,
modifier = Modifier.padding(10.dp),
color = MaterialTheme.colorScheme.onSecondaryContainer,
@@ -41,6 +41,16 @@ import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.KeyboardArrowDown
import androidx.compose.material.icons.outlined.KeyboardArrowLeft
import androidx.compose.material.icons.outlined.KeyboardArrowRight
import androidx.compose.material.icons.outlined.KeyboardArrowUp
import androidx.compose.material.icons.outlined.PowerSettingsNew
import androidx.compose.material.icons.outlined.Remove
import androidx.compose.material.icons.outlined.VolumeOff
import androidx.compose.material.icons.outlined.Tv
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -333,7 +343,7 @@ private fun AcControlPanel(
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = if (acState.power) "● 运行中" else "○ 已关机",
text = if (acState.power) "运行中" else "已关机",
color = if (acState.power) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
fontWeight = FontWeight.Bold,
)
@@ -345,7 +355,7 @@ private fun AcControlPanel(
.background(if (acState.power) Color(0xFFFF5252) else MaterialTheme.colorScheme.outline)
.testTag("ac_power_toggle"),
) {
Text("⏻", color = Color.White, fontSize = 20.sp, fontWeight = FontWeight.Bold)
Icon(Icons.Outlined.PowerSettingsNew, contentDescription = "电源", tint = Color.White)
}
}
@@ -371,14 +381,14 @@ private fun AcControlPanel(
modifier = Modifier.size(56.dp).testTag("ac_temp_down"),
shape = CircleShape,
) {
Text("-", fontSize = 24.sp, fontWeight = FontWeight.Bold)
Icon(Icons.Outlined.Remove, contentDescription = "降低温度")
}
Button(
onClick = { onAdjustTemp(1) },
modifier = Modifier.size(56.dp).testTag("ac_temp_up"),
shape = CircleShape,
) {
Text("+", fontSize = 24.sp, fontWeight = FontWeight.Bold)
Icon(Icons.Outlined.Add, contentDescription = "升高温度")
}
}
}
@@ -421,19 +431,19 @@ private fun AcControlPanel(
FilterChip(
selected = acState.verticalSwing,
onClick = onToggleVSwing,
label = { Text("↕ 上下扫风") },
label = { Text("上下扫风") },
modifier = Modifier.weight(1f),
)
FilterChip(
selected = acState.horizontalSwing,
onClick = onToggleHSwing,
label = { Text("↔ 左右扫风") },
label = { Text("左右扫风") },
modifier = Modifier.weight(1f),
)
FilterChip(
selected = acState.eco,
onClick = onToggleEco,
label = { Text("🌱 节能 ECO") },
label = { Text("节能") },
modifier = Modifier.weight(1f),
)
}
@@ -463,9 +473,9 @@ private fun TvControlPanel(
horizontalArrangement = Arrangement.SpaceAround,
verticalAlignment = Alignment.CenterVertically,
) {
InteractiveRemoteButton("TV_POWER", "⏻ 电源", Color(0xFFFF5252), bindingMap["TV_POWER"], isLearnMode, learningButtonId, sendingButtonId, onButtonClick)
InteractiveRemoteButton("TV_MUTE", "🔇 静音", MaterialTheme.colorScheme.secondary, bindingMap["TV_MUTE"], isLearnMode, learningButtonId, sendingButtonId, onButtonClick)
InteractiveRemoteButton("TV_SOURCE", "📺 信号源", MaterialTheme.colorScheme.secondary, bindingMap["TV_SOURCE"], isLearnMode, learningButtonId, sendingButtonId, onButtonClick)
InteractiveRemoteButton("TV_POWER", "电源", Color(0xFFFF5252), bindingMap["TV_POWER"], isLearnMode, learningButtonId, sendingButtonId, onButtonClick)
InteractiveRemoteButton("TV_MUTE", "静音", MaterialTheme.colorScheme.secondary, bindingMap["TV_MUTE"], isLearnMode, learningButtonId, sendingButtonId, onButtonClick)
InteractiveRemoteButton("TV_SOURCE", "信号源", MaterialTheme.colorScheme.secondary, bindingMap["TV_SOURCE"], isLearnMode, learningButtonId, sendingButtonId, onButtonClick)
}
Spacer(modifier = Modifier.height(8.dp))
@@ -482,7 +492,7 @@ private fun TvControlPanel(
onClick = { onButtonClick("TV_NAV_UP") },
modifier = Modifier.align(Alignment.TopCenter).padding(top = 10.dp).testTag("tv_nav_up"),
) {
ButtonIndicatorText("TV_NAV_UP", "▲", learningButtonId, sendingButtonId)
ButtonIndicatorText("TV_NAV_UP", "上", learningButtonId, sendingButtonId)
}
// 下
@@ -490,7 +500,7 @@ private fun TvControlPanel(
onClick = { onButtonClick("TV_NAV_DOWN") },
modifier = Modifier.align(Alignment.BottomCenter).padding(bottom = 10.dp).testTag("tv_nav_down"),
) {
ButtonIndicatorText("TV_NAV_DOWN", "▼", learningButtonId, sendingButtonId)
ButtonIndicatorText("TV_NAV_DOWN", "下", learningButtonId, sendingButtonId)
}
// 左
@@ -498,7 +508,7 @@ private fun TvControlPanel(
onClick = { onButtonClick("TV_NAV_LEFT") },
modifier = Modifier.align(Alignment.CenterStart).padding(start = 10.dp).testTag("tv_nav_left"),
) {
ButtonIndicatorText("TV_NAV_LEFT", "◀", learningButtonId, sendingButtonId)
ButtonIndicatorText("TV_NAV_LEFT", "左", learningButtonId, sendingButtonId)
}
// 右
@@ -506,7 +516,7 @@ private fun TvControlPanel(
onClick = { onButtonClick("TV_NAV_RIGHT") },
modifier = Modifier.align(Alignment.CenterEnd).padding(end = 10.dp).testTag("tv_nav_right"),
) {
ButtonIndicatorText("TV_NAV_RIGHT", "▶", learningButtonId, sendingButtonId)
ButtonIndicatorText("TV_NAV_RIGHT", "右", learningButtonId, sendingButtonId)
}
// OK 居中大按钮
@@ -554,10 +564,10 @@ private fun TvControlPanel(
) {
Text("频道 CH", fontWeight = FontWeight.Bold, fontSize = 12.sp)
Button(onClick = { onButtonClick("TV_CH_UP") }, modifier = Modifier.size(54.dp), shape = RoundedCornerShape(12.dp)) {
ButtonIndicatorText("TV_CH_UP", "▲", learningButtonId, sendingButtonId)
ButtonIndicatorText("TV_CH_UP", "频道上调", learningButtonId, sendingButtonId)
}
Button(onClick = { onButtonClick("TV_CH_DOWN") }, modifier = Modifier.size(54.dp), shape = RoundedCornerShape(12.dp)) {
ButtonIndicatorText("TV_CH_DOWN", "▼", learningButtonId, sendingButtonId)
ButtonIndicatorText("TV_CH_DOWN", "频道下调", learningButtonId, sendingButtonId)
}
}
}
@@ -583,8 +593,8 @@ private fun MediaPlayerControlPanel(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
) {
InteractiveRemoteButton("MEDIA_POWER", "⏻ 电源", Color(0xFFFF5252), bindingMap["MEDIA_POWER"], isLearnMode, learningButtonId, sendingButtonId, onButtonClick)
InteractiveRemoteButton("MEDIA_MUTE", "🔇 静音", MaterialTheme.colorScheme.secondary, bindingMap["MEDIA_MUTE"], isLearnMode, learningButtonId, sendingButtonId, onButtonClick)
InteractiveRemoteButton("MEDIA_POWER", "电源", Color(0xFFFF5252), bindingMap["MEDIA_POWER"], isLearnMode, learningButtonId, sendingButtonId, onButtonClick)
InteractiveRemoteButton("MEDIA_MUTE", "静音", MaterialTheme.colorScheme.secondary, bindingMap["MEDIA_MUTE"], isLearnMode, learningButtonId, sendingButtonId, onButtonClick)
}
Spacer(modifier = Modifier.height(16.dp))
@@ -642,13 +652,13 @@ private fun GenericGridControlPanel(
) {
Text("按键列表 (${bindings.size})", fontWeight = FontWeight.Bold, fontSize = 16.sp)
Button(onClick = onAddButton, modifier = Modifier.testTag("grid_add_key_button")) {
Text("➕ 添加按键")
Text("添加按键")
}
}
if (bindings.isEmpty()) {
Box(modifier = Modifier.fillMaxWidth().weight(1f), contentAlignment = Alignment.Center) {
Text("暂无自定义按键,点击上方【➕ 添加按键】新建", color = MaterialTheme.colorScheme.onSurfaceVariant)
Text("暂无自定义按键,请使用上方添加操作新建", color = MaterialTheme.colorScheme.onSurfaceVariant)
}
} else {
LazyVerticalGrid(
@@ -697,9 +707,9 @@ private fun GridButtonCard(
Column(modifier = Modifier.weight(1f)) {
Text(binding.displayName, fontWeight = FontWeight.Bold, fontSize = 15.sp)
val statusText = when {
isLearning -> "🟡 正在录制信号..."
binding.status == InfraredKeyStatus.READY -> "🟢 已就绪 (Slot ${binding.assignedSlot ?: "动态"})"
else -> "⚪ 待录制 (点击录码)"
isLearning -> "正在录制信号..."
binding.status == InfraredKeyStatus.READY -> "已就绪(槽位 ${binding.assignedSlot ?: "动态"})"
else -> "待录制(点击录码)"
}
Text(statusText, fontSize = 11.sp, color = MaterialTheme.colorScheme.onSurfaceVariant)
}
@@ -712,7 +722,7 @@ private fun GridButtonCard(
onClick = onDelete,
modifier = Modifier.size(36.dp).testTag("delete_key_${binding.buttonId}"),
) {
Text("🗑️", fontSize = 15.sp)
Text("删除", fontSize = 12.sp)
}
}
}
@@ -756,7 +766,7 @@ private fun ButtonIndicatorText(
sendingButtonId: String?,
) {
if (learningButtonId == buttonId) {
Text("🟡 录制中", fontSize = 12.sp, fontWeight = FontWeight.Bold)
Text("录制中", fontSize = 12.sp, fontWeight = FontWeight.Bold)
} else if (sendingButtonId == buttonId) {
CircularProgressIndicator(modifier = Modifier.size(16.dp), color = Color.White)
} else {
@@ -26,24 +26,24 @@ data class RemoteButtonSpec(
object RemoteSceneConfig {
object AirConditioner {
val POWER = RemoteButtonSpec("AC_POWER", "1", R.string.infrared_key_ac_power, "空调-电源", "⏻")
val TEMP_UP = RemoteButtonSpec("AC_TEMP_UP", "2", R.string.infrared_key_ac_temp_up, "空调-温度+", "▲")
val TEMP_DOWN = RemoteButtonSpec("AC_TEMP_DOWN", "3", R.string.infrared_key_ac_temp_down, "空调-温度-", "▼")
val MODE = RemoteButtonSpec("AC_MODE", "4", R.string.infrared_key_ac_mode, "空调-模式", "模式 ❄/☀")
val FAN = RemoteButtonSpec("AC_FAN", "5", R.string.infrared_key_ac_fan, "空调-风速", "风速 💨")
val SWING = RemoteButtonSpec("AC_SWING", "6", R.string.infrared_key_ac_swing, "空调-扫风", "扫风 ↔")
val TIMER = RemoteButtonSpec("AC_TIMER", "7", R.string.infrared_key_ac_timer, "空调-定时", "定时 ⏱")
val POWER = RemoteButtonSpec("AC_POWER", "1", R.string.infrared_key_ac_power, "空调-电源", "电源")
val TEMP_UP = RemoteButtonSpec("AC_TEMP_UP", "2", R.string.infrared_key_ac_temp_up, "空调-温度+", "升温")
val TEMP_DOWN = RemoteButtonSpec("AC_TEMP_DOWN", "3", R.string.infrared_key_ac_temp_down, "空调-温度-", "降温")
val MODE = RemoteButtonSpec("AC_MODE", "4", R.string.infrared_key_ac_mode, "空调-模式", "模式")
val FAN = RemoteButtonSpec("AC_FAN", "5", R.string.infrared_key_ac_fan, "空调-风速", "风速")
val SWING = RemoteButtonSpec("AC_SWING", "6", R.string.infrared_key_ac_swing, "空调-扫风", "扫风")
val TIMER = RemoteButtonSpec("AC_TIMER", "7", R.string.infrared_key_ac_timer, "空调-定时", "定时")
val buttons = listOf(POWER, TEMP_UP, TEMP_DOWN, MODE, FAN, SWING, TIMER)
}
object Television {
val POWER = RemoteButtonSpec("TV_POWER", "21", R.string.infrared_key_tv_power, "电视-电源", "⏻")
val MUTE = RemoteButtonSpec("TV_MUTE", "22", R.string.infrared_key_tv_mute, "电视-静音", "🔇")
val NAV_UP = RemoteButtonSpec("TV_NAV_UP", "23", R.string.infrared_key_tv_nav_up, "电视-上", "▲")
val NAV_DOWN = RemoteButtonSpec("TV_NAV_DOWN", "24", R.string.infrared_key_tv_nav_down, "电视-下", "▼")
val NAV_LEFT = RemoteButtonSpec("TV_NAV_LEFT", "25", R.string.infrared_key_tv_nav_left, "电视-左", "◀")
val NAV_RIGHT = RemoteButtonSpec("TV_NAV_RIGHT", "26", R.string.infrared_key_tv_nav_right, "电视-右", "▶")
val POWER = RemoteButtonSpec("TV_POWER", "21", R.string.infrared_key_tv_power, "电视-电源", "电源")
val MUTE = RemoteButtonSpec("TV_MUTE", "22", R.string.infrared_key_tv_mute, "电视-静音", "静音")
val NAV_UP = RemoteButtonSpec("TV_NAV_UP", "23", R.string.infrared_key_tv_nav_up, "电视-上", "上")
val NAV_DOWN = RemoteButtonSpec("TV_NAV_DOWN", "24", R.string.infrared_key_tv_nav_down, "电视-下", "下")
val NAV_LEFT = RemoteButtonSpec("TV_NAV_LEFT", "25", R.string.infrared_key_tv_nav_left, "电视-左", "左")
val NAV_RIGHT = RemoteButtonSpec("TV_NAV_RIGHT", "26", R.string.infrared_key_tv_nav_right, "电视-右", "右")
val OK = RemoteButtonSpec("TV_OK", "27", R.string.infrared_key_tv_ok, "电视-确定", "OK")
val VOL_UP = RemoteButtonSpec("TV_VOL_UP", "28", R.string.infrared_key_tv_vol_up, "电视-音量+", "VOL +")
val VOL_DOWN = RemoteButtonSpec("TV_VOL_DOWN", "29", R.string.infrared_key_tv_vol_down, "电视-音量-", "VOL -")
@@ -45,6 +45,8 @@ import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.flagship.abox.manager.designsystem.ABoxSurface
import com.flagship.abox.manager.designsystem.ABoxIconButton
import com.flagship.abox.manager.designsystem.icon.ABoxIconKey
import com.flagship.abox.manager.infrared.R
import com.flagship.abox.manager.infrared.remote.InfraredRemoteUiState
import com.flagship.abox.manager.infrared.remote.InfraredRemoteViewModel
@@ -158,12 +160,12 @@ internal fun InfraredRemoteScreen(
}
// 按键管理 / 设置入口按钮
IconButton(
ABoxIconButton(
key = ABoxIconKey.EDIT,
contentDescription = "打开红外设置",
onClick = onOpenSettings,
modifier = Modifier.testTag("remote_settings_button"),
) {
Text("⚙️", fontSize = 20.sp)
}
)
},
)
},
@@ -35,12 +35,12 @@
<string name="infrared_remote_title">红外遥控器</string>
<string name="infrared_remote_recording">录制中</string>
<string name="infrared_remote_learning_mode">学习模式</string>
<string name="infrared_remote_learning_banner">🔴 学习模式已开启:点击任意按键开始录制实体遥控器信号</string>
<string name="infrared_remote_scene_ac">❄️ 空调面板</string>
<string name="infrared_remote_scene_tv">📺 电视面板</string>
<string name="infrared_remote_learning_banner">学习模式已开启:点击任意按键开始录制实体遥控器信号</string>
<string name="infrared_remote_scene_ac">空调面板</string>
<string name="infrared_remote_scene_tv">电视面板</string>
<string name="infrared_remote_settings">设置</string>
<string name="infrared_msg_learning_mode_enabled">🔴 学习模式已开启:点击任意按键开始录制</string>
<string name="infrared_msg_learning_mode_enabled">学习模式已开启:点击任意按键开始录制</string>
<string name="infrared_msg_recording_key">正在录制【%1$s】(槽位 %2$s),请按下实体遥控器按键…</string>
<string name="infrared_msg_learned_success">【%1$s】录制成功</string>
<string name="infrared_msg_key_not_learned">按键【%1$s】尚未学习,开启右上角学习模式即可录制</string>
@@ -51,8 +51,8 @@
<string name="infrared_label_temp_control">温度调节</string>
<string name="infrared_label_vol">音量</string>
<string name="infrared_label_ch">频道</string>
<string name="infrared_label_cool_mode">❄️ 制冷模式</string>
<string name="infrared_label_ac_status">💨 自动风速 | ↔ 自动扫风</string>
<string name="infrared_label_cool_mode">制冷模式</string>
<string name="infrared_label_ac_status">自动风速 | 自动扫风</string>
<string name="infrared_key_ac_power">空调-电源</string>
<string name="infrared_key_ac_temp_up">空调-升温</string>
@@ -98,10 +98,10 @@
<string name="infrared_hub_static_quota">静态占用:%1$d</string>
<string name="infrared_hub_dynamic_scratch">动态缓冲:Slot %1$s</string>
<string name="infrared_hub_remotes_title">虚拟遥控器</string>
<string name="infrared_hub_no_remotes">暂无虚拟遥控器,点击右上角或下方 ➕ 添加</string>
<string name="infrared_hub_no_remotes">暂无虚拟遥控器,请使用添加操作</string>
<string name="infrared_hub_add_remote">添加遥控器</string>
<string name="infrared_hub_mode_static">🚀 静态独占(%1$s 槽位)</string>
<string name="infrared_hub_mode_dynamic">📦 动态缓冲(共用 Slot %1$s)</string>
<string name="infrared_hub_mode_static">静态独占(%1$s 槽位)</string>
<string name="infrared_hub_mode_dynamic">动态缓冲(共用槽位 %1$s)</string>
<string name="infrared_hub_create_dialog_title">添加虚拟遥控器</string>
<string name="infrared_hub_device_type_label">设备类型</string>
<string name="infrared_hub_brand_label">预设码库 / 品牌</string>
@@ -110,8 +110,8 @@
<string name="infrared_hub_trans_mode_dynamic_desc">节省槽位(0 额外槽位),现场写码发射(~80ms)</string>
<string name="infrared_hub_quota_insufficient">硬件槽位不足,请选择动态写码模式</string>
<string name="infrared_hub_raw_keys_button">硬件槽位与底层按键管理</string>
<string name="infrared_hub_device_type_tv">📺 电视机 / 电视盒子</string>
<string name="infrared_hub_device_type_ac">❄️ 空调设备</string>
<string name="infrared_hub_device_type_tv">电视机 / 电视盒子</string>
<string name="infrared_hub_device_type_ac">空调设备</string>
<string name="infrared_hub_device_type_fan">🌀 电风扇 / 空气净化器</string>
<string name="infrared_hub_device_type_custom">🎛️ 自定义面板</string>
<string name="infrared_hub_device_type_custom">自定义面板</string>
</resources>
@@ -36,12 +36,12 @@
<string name="infrared_remote_recording">Recording</string>
<string name="infrared_hub_my_remotes">My Remotes</string>
<string name="infrared_remote_learning_mode">Learn Mode</string>
<string name="infrared_remote_learning_banner">🔴 Learn mode active: tap any button to record</string>
<string name="infrared_remote_scene_ac">❄️ Air Conditioner</string>
<string name="infrared_remote_scene_tv">📺 Television</string>
<string name="infrared_remote_learning_banner">Learn mode active: tap any button to record</string>
<string name="infrared_remote_scene_ac">Air Conditioner</string>
<string name="infrared_remote_scene_tv">Television</string>
<string name="infrared_remote_settings">Settings</string>
<string name="infrared_msg_learning_mode_enabled">🔴 Learn mode active: tap any button to record</string>
<string name="infrared_msg_learning_mode_enabled">Learn mode active: tap any button to record</string>
<string name="infrared_msg_recording_key">Recording [%1$s] (Slot %2$s), press remote button…</string>
<string name="infrared_msg_learned_success">[%1$s] recorded successfully</string>
<string name="infrared_msg_key_not_learned">Button [%1$s] is not learned. Enable learn mode to record.</string>
@@ -52,8 +52,8 @@
<string name="infrared_label_temp_control">Temp Control</string>
<string name="infrared_label_vol">VOL</string>
<string name="infrared_label_ch">CH</string>
<string name="infrared_label_cool_mode">❄️ Cool Mode</string>
<string name="infrared_label_ac_status">💨 Auto Fan | ↔ Swing</string>
<string name="infrared_label_cool_mode">Cool Mode</string>
<string name="infrared_label_ac_status">Auto Fan | Swing</string>
<string name="infrared_key_ac_power">AC Power</string>
<string name="infrared_key_ac_temp_up">AC Temp +</string>
@@ -100,8 +100,8 @@
<string name="infrared_hub_remotes_title">Virtual Remotes</string>
<string name="infrared_hub_no_remotes">No virtual remotes added yet. Tap + to add one.</string>
<string name="infrared_hub_add_remote">Add Remote</string>
<string name="infrared_hub_mode_static">🚀 Static Mode (%1$s slots)</string>
<string name="infrared_hub_mode_dynamic">📦 Dynamic Mode (Scratch Slot %1$s)</string>
<string name="infrared_hub_mode_static">Static Mode (%1$s slots)</string>
<string name="infrared_hub_mode_dynamic">Dynamic Mode (Scratch Slot %1$s)</string>
<string name="infrared_hub_create_dialog_title">Add Virtual Remote</string>
<string name="infrared_hub_device_type_label">Device Type</string>
<string name="infrared_hub_brand_label">Brand / Preset Library</string>
@@ -110,8 +110,8 @@
<string name="infrared_hub_trans_mode_dynamic_desc">Saves slots (0 extra slots), writes code on-the-fly (~80ms)</string>
<string name="infrared_hub_quota_insufficient">Slot quota exceeded. Please choose Dynamic mode.</string>
<string name="infrared_hub_raw_keys_button">Hardware Slot / Raw Key Management</string>
<string name="infrared_hub_device_type_tv">📺 Television (TV)</string>
<string name="infrared_hub_device_type_ac">❄️ Air Conditioner (AC)</string>
<string name="infrared_hub_device_type_tv">Television (TV)</string>
<string name="infrared_hub_device_type_ac">Air Conditioner (AC)</string>
<string name="infrared_hub_device_type_fan">🌀 Fan / Air Purifier</string>
<string name="infrared_hub_device_type_custom">🎛️ Custom Panel</string>
<string name="infrared_hub_device_type_custom">Custom Panel</string>
</resources>