Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
19f469b
feat(i18n): add Traditional Chinese (zh-TW) localization
yangyws Aug 5, 2026
a1f42b7
feat(privd): support Traditional Chinese in Auto Setup
yangyws Aug 5, 2026
6fa4442
fix(privd): detect the Developer options screen in every supported lo…
yangyws Aug 5, 2026
607c202
feat(i18n): sync Traditional Chinese with the current upstream baseline
yangyws Aug 6, 2026
bfb0ff6
Merge remote-tracking branch 'origin/main' into feature/traditional-c…
yangyws Aug 8, 2026
28f814a
feat(i18n): sync 0.8.0 strings, make developerOptionsKeywords explici…
yangyws Aug 8, 2026
5d9f696
fix(autosetup): refine targetStage calculation, recursive pair dialog…
yangyws Aug 9, 2026
8f2d4c5
refactor(i18n): focus PR strictly on Traditional Chinese text localiz…
yangyws Aug 11, 2026
a4008ab
feat(i18n): restore AutoSetupLanguageConfig for zh-TW support
yangyws Aug 11, 2026
c8194cd
fix(i18n): refine Traditional Chinese wording and fix sub-screen dete…
yangyws Aug 11, 2026
37eaed3
test(core): remove redundant developerOptionsKeywords test and clean …
Aug 11, 2026
48c5f11
fix(i18n): resolve AAPT2 string format warnings and sync Privileged M…
Aug 11, 2026
066ee5d
Merge remote-tracking branch 'origin/main' into feature/traditional-c…
yangyws Aug 12, 2026
fa33967
Merge remote-tracking branch 'origin/main' into feature/traditional-c…
yangyws Aug 14, 2026
41f253c
feat(i18n): complete Traditional Chinese localization for 0.9.0 and o…
yangyws Aug 14, 2026
6c587b8
fix(i18n): refine filled icon translation to 實心 in Traditional Chinese
yangyws Aug 15, 2026
bc8bad8
chore(i18n): rename duplicate profile/layout to 複製設定檔/複製配置 in zh-rTW
yangyws Aug 15, 2026
2406f1d
fix(macropad): use quick_menu_edit_layout as EditorTopBar title
yangyws Aug 15, 2026
0ae5666
chore(i18n): standardize display terminology to 主螢幕/副螢幕 and localize …
yangyws Aug 15, 2026
3fc95c4
chore(i18n): translate idle hero title to Megingiard 副螢幕輔助中心 and swit…
yangyws Aug 15, 2026
059861c
Merge remote-tracking branch 'origin/main' into feature/traditional-c…
yangyws Aug 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,21 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import java.util.Locale
import java.util.UUID

private const val TAG = "MacroPadState"
private const val MP_DEFAULT_PROFILE_NAME = "Profile"
private const val MP_DEFAULT_LAYOUT_NAME = "Layout"
private const val DUPLICATE_BUTTON_OFFSET = 0.05f

private fun defaultInitialName(): String =
when (Locale.getDefault().language.lowercase()) {
"zh" -> "預設"
"de" -> "Standard"
else -> "Default"
}

private fun List<String>.nextUniqueName(
baseName: String,
fallback: String,
Expand Down Expand Up @@ -170,13 +178,14 @@ object MacroPadState {
needsSave = true
val defaultId = UUID.randomUUID().toString()
val defaultLayoutId = UUID.randomUUID().toString()
val initialName = defaultInitialName()
listOf(
PadProfile(
id = defaultId,
name = "Default",
name = initialName,
layouts =
listOf(
PadLayout(id = defaultLayoutId, name = "Default", mirrorCutouts = listOf(ScreenCutout.createDefault())),
PadLayout(id = defaultLayoutId, name = initialName, mirrorCutouts = listOf(ScreenCutout.createDefault())),
),
activeLayoutId = defaultLayoutId,
),
Expand Down Expand Up @@ -337,11 +346,12 @@ object MacroPadState {
fun restoreDefaults() {
val defaultId = UUID.randomUUID().toString()
val defaultLayoutId = UUID.randomUUID().toString()
val initialName = defaultInitialName()
val defaultProfile =
PadProfile(
id = defaultId,
name = "Default",
layouts = listOf(PadLayout(id = defaultLayoutId, name = "Default", mirrorCutouts = listOf(ScreenCutout.createDefault()))),
name = initialName,
layouts = listOf(PadLayout(id = defaultLayoutId, name = initialName, mirrorCutouts = listOf(ScreenCutout.createDefault()))),
activeLayoutId = defaultLayoutId,
)
_profiles.value = listOf(defaultProfile)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import java.util.Locale
import java.util.UUID

/**
Expand All @@ -23,14 +24,18 @@ import java.util.UUID
@OptIn(ExperimentalCoroutinesApi::class)
class MacroPadStateTest {
private val testDispatcher = UnconfinedTestDispatcher()
private lateinit var originalLocale: Locale

@Before
fun setUp() {
originalLocale = Locale.getDefault()
Locale.setDefault(Locale.US)
Dispatchers.setMain(testDispatcher)
}

@After
fun tearDown() {
Locale.setDefault(originalLocale)
Dispatchers.resetMain()
}

Expand Down Expand Up @@ -62,6 +67,26 @@ class MacroPadStateTest {
assertEquals(defaultLayout, MacroPadState.activeLayout.value)
}

@Test
fun `loadFrom with empty list in Traditional Chinese locale generates localized default name`() {
Locale.setDefault(Locale.TRADITIONAL_CHINESE)
MacroPadState.loadFrom(emptyList(), null)

val defaultProfile = MacroPadState.profiles.value.first()
assertEquals("預設", defaultProfile.name)
assertEquals("預設", defaultProfile.layouts.first().name)
}

@Test
fun `loadFrom with empty list in German locale generates localized default name`() {
Locale.setDefault(Locale.GERMANY)
MacroPadState.loadFrom(emptyList(), null)

val defaultProfile = MacroPadState.profiles.value.first()
assertEquals("Standard", defaultProfile.name)
assertEquals("Standard", defaultProfile.layouts.first().name)
}

@Test
fun `loadFrom with existing profiles preserves them`() {
// Given existing profiles
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ private fun KeyboardModeToggleButton(
horizontalArrangement = Arrangement.Center,
) {
Text(
text = "Ergo",
text = stringResource(R.string.keyboard_mode_ergo),
color = ergoColor,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
Expand Down Expand Up @@ -216,7 +216,7 @@ private fun KeyboardModeToggleButton(
)
Spacer(modifier = Modifier.width(6.dp))
Text(
text = "Full",
text = stringResource(R.string.keyboard_mode_full),
color = fullColor,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ private fun EditorTopBar(
TopAppBar(
title = {
Text(
text = stringResource(R.string.macropad_editor_title_edit_profile),
text = stringResource(R.string.quick_menu_edit_layout),
color = colors.onSurface,
style = MaterialTheme.typography.titleMedium,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ private fun ModeToggleButton(
horizontalArrangement = Arrangement.Center,
) {
Text(
text = "Mouse",
text = stringResource(R.string.touchpad_mode_mouse),
color = mouseColor,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
Expand Down Expand Up @@ -767,7 +767,7 @@ private fun ModeToggleButton(
)
Spacer(modifier = Modifier.width(6.dp))
Text(
text = "Touch",
text = stringResource(R.string.touchpad_mode_touch),
color = touchColor,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
Expand Down
4 changes: 4 additions & 0 deletions companion/ui/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,10 @@ Einstellungen öffnen, um ein Layout zu erstellen.</string>
<string name="focus_change_artwork_title">Cover-Artwork ändern</string>

<!-- Touchpad settings -->
<string name="keyboard_mode_ergo">Ergo</string>
<string name="keyboard_mode_full">Voll</string>
<string name="touchpad_mode_mouse">Maus</string>
<string name="touchpad_mode_touch">Touch</string>
<string name="settings_touchpad_title">Touchpad-Einstellungen</string>
<string name="settings_section_relative_mouse">Relative-Maus-Modus</string>
<string name="settings_section_absolute_touch">Absolut-Touch-Modus</string>
Expand Down
Loading