Skip to content

Commit f5bd82b

Browse files
fix(android): replace clipboard auto-detect with manual Paste button (#344)
Android 13+ restricts clipboard access for background-to-foreground transitions — the auto-detect banner never appeared on resume. Replace with a permanent Paste button that reads clipboard on tap (user interaction grants clipboard permission). Also: Export button is now icon-only (share icon) to save space. Co-authored-by: yyoyoian-pixel <279225925+yyoyoian-pixel@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 915dba7 commit f5bd82b

1 file changed

Lines changed: 19 additions & 49 deletions

File tree

android/app/src/main/java/com/therealaleph/mhrv/ui/ConfigSharing.kt

Lines changed: 19 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,9 @@ fun ConfigSharingBar(
6363
val clipboard = LocalClipboardManager.current
6464
val scope = rememberCoroutineScope()
6565

66-
val clipText = clipboard.getText()?.text.orEmpty()
67-
val hasConfigInClipboard = clipText.isNotEmpty() && ConfigStore.looksLikeConfig(clipText)
68-
6966
var showExportDialog by remember { mutableStateOf(false) }
7067
var showImportConfirm by remember { mutableStateOf(false) }
7168
var pendingImport by remember { mutableStateOf<MhrvConfig?>(null) }
72-
var showQrDialog by remember { mutableStateOf(false) }
7369

7470
// QR scanner launcher — fires the ZXing embedded scanner activity.
7571
val scanLauncher = rememberLauncherForActivityResult(ScanContract()) { result ->
@@ -83,58 +79,32 @@ fun ConfigSharingBar(
8379
}
8480
}
8581

86-
// --- Paste from clipboard banner ---
87-
if (hasConfigInClipboard) {
88-
Card(
89-
modifier = Modifier.fillMaxWidth(),
90-
colors = CardDefaults.cardColors(
91-
containerColor = MaterialTheme.colorScheme.primaryContainer,
92-
),
93-
) {
94-
Row(
95-
modifier = Modifier
96-
.fillMaxWidth()
97-
.padding(horizontal = 12.dp, vertical = 8.dp),
98-
verticalAlignment = Alignment.CenterVertically,
99-
horizontalArrangement = Arrangement.SpaceBetween,
100-
) {
101-
Text(
102-
"Config detected in clipboard",
103-
style = MaterialTheme.typography.labelMedium,
104-
color = MaterialTheme.colorScheme.onPrimaryContainer,
105-
modifier = Modifier.weight(1f),
106-
)
107-
FilledTonalButton(
108-
onClick = {
109-
val decoded = ConfigStore.decode(clipText)
110-
if (decoded != null) {
111-
pendingImport = decoded
112-
showImportConfirm = true
113-
} else {
114-
scope.launch { onSnackbar(ctx.getString(R.string.snack_invalid_config)) }
115-
}
116-
},
117-
) {
118-
Icon(Icons.Default.ContentPaste, null, modifier = Modifier.size(18.dp))
119-
Spacer(Modifier.width(4.dp))
120-
Text(stringResource(R.string.btn_import_clipboard))
121-
}
122-
}
123-
}
124-
}
125-
126-
// --- Export + Scan row ---
82+
// --- Export + Paste + Scan row ---
12783
Row(
12884
modifier = Modifier.fillMaxWidth(),
12985
horizontalArrangement = Arrangement.spacedBy(8.dp),
13086
) {
87+
IconButton(onClick = { showExportDialog = true }) {
88+
Icon(Icons.Default.Share, contentDescription = stringResource(R.string.btn_export_config))
89+
}
90+
// Manual paste — reads clipboard on tap. Android 13+ restricts
91+
// background clipboard access, so auto-detect doesn't work.
92+
// User interaction (tap) grants clipboard permission.
13193
OutlinedButton(
132-
onClick = { showExportDialog = true },
133-
modifier = Modifier.weight(1f),
94+
onClick = {
95+
val text = clipboard.getText()?.text.orEmpty()
96+
val decoded = ConfigStore.decode(text)
97+
if (decoded != null) {
98+
pendingImport = decoded
99+
showImportConfirm = true
100+
} else {
101+
scope.launch { onSnackbar(ctx.getString(R.string.snack_invalid_config)) }
102+
}
103+
},
134104
) {
135-
Icon(Icons.Default.Share, null, modifier = Modifier.size(18.dp))
105+
Icon(Icons.Default.ContentPaste, null, modifier = Modifier.size(18.dp))
136106
Spacer(Modifier.width(4.dp))
137-
Text(stringResource(R.string.btn_export_config))
107+
Text("Paste")
138108
}
139109
OutlinedButton(
140110
onClick = {

0 commit comments

Comments
 (0)