@@ -16,12 +16,16 @@ import androidx.compose.foundation.verticalScroll
1616import androidx.compose.material.icons.Icons
1717import androidx.compose.material.icons.outlined.*
1818import androidx.compose.material3.ExperimentalMaterial3Api
19+ import androidx.compose.material3.Icon
1920import androidx.compose.material3.MaterialTheme
21+ import androidx.compose.material3.Text
2022import androidx.compose.runtime.*
2123import androidx.compose.ui.Alignment
2224import androidx.compose.ui.Modifier
2325import androidx.compose.ui.platform.LocalContext
26+ import androidx.compose.ui.res.painterResource
2427import androidx.compose.ui.res.stringResource
28+ import androidx.compose.ui.text.font.FontWeight
2529import androidx.compose.ui.unit.dp
2630import androidx.core.net.toUri
2731import androidx.lifecycle.Lifecycle
@@ -242,72 +246,53 @@ fun SystemTabContent(
242246
243247 SectionCard {
244248 Column {
245- // Keystore Import
246- BaseSettingsItem (
247- onClick = onImportKeystore,
249+ // Keystore
250+ ImportExportRow (
248251 leadingContent = { MorpheIcon (icon = Icons .Outlined .Key ) },
249- title = stringResource(R .string.settings_system_import_keystore),
250- description = stringResource(R .string.settings_system_import_keystore_description)
251- )
252-
253- MorpheSettingsDivider ()
254-
255- // Keystore Export
256- BaseSettingsItem (
257- onClick = {
252+ title = stringResource(R .string.settings_system_keystore),
253+ description = stringResource(R .string.settings_system_import_keystore_description),
254+ onImport = onImportKeystore,
255+ onExport = {
258256 if (! importExportViewModel.canExport()) {
259257 context.toast(keystoreUnavailable)
260258 } else {
261259 onExportKeystore()
262260 }
263- },
264- leadingContent = { MorpheIcon (icon = Icons .Outlined .Upload ) },
265- title = stringResource(R .string.settings_system_export_keystore),
266- description = stringResource(R .string.settings_system_export_keystore_description)
261+ }
267262 )
268- }
269- }
270263
271- SectionCard {
272- Column {
273- // Manager Settings Import
274- BaseSettingsItem (
275- onClick = onImportSettings,
276- leadingContent = { MorpheIcon (icon = Icons .Outlined .Download ) },
277- title = stringResource(R .string.settings_system_import_manager_settings),
278- description = stringResource(R .string.settings_system_import_manager_settings_description)
264+ MorpheSettingsDivider ()
265+
266+ // Manager Settings
267+ ImportExportRow (
268+ leadingContent = {
269+ Icon (
270+ painter = painterResource(R .drawable.ic_notification),
271+ contentDescription = null ,
272+ tint = MaterialTheme .colorScheme.primary,
273+ modifier = Modifier .size(24 .dp)
274+ )
275+ },
276+ title = stringResource(R .string.settings_system_morphe_settings),
277+ description = stringResource(R .string.settings_system_import_manager_settings_description),
278+ onImport = onImportSettings,
279+ onExport = onExportSettings
279280 )
280281
281282 MorpheSettingsDivider ()
282283
283- // Manager Settings Export
284- BaseSettingsItem (
285- onClick = onExportSettings,
286- leadingContent = { MorpheIcon (icon = Icons .Outlined .Upload ) },
287- title = stringResource(R .string.settings_system_export_manager_settings),
288- description = stringResource(R .string.settings_system_export_manager_settings_description)
284+ // Debug Logs
285+ ImportExportRow (
286+ leadingContent = { MorpheIcon (icon = Icons .Outlined .BugReport ) },
287+ title = stringResource(R .string.settings_system_debug),
288+ description = stringResource(R .string.settings_system_export_debug_logs_description),
289+ onImport = null ,
290+ onExport = onExportDebugLogs
289291 )
290292 }
291293 }
292294 }
293295
294- // Debug Logs (Expert mode only)
295- if (useExpertMode) {
296- SectionTitle (
297- text = stringResource(R .string.settings_system_debug),
298- icon = Icons .Outlined .BugReport
299- )
300-
301- SectionCard {
302- BaseSettingsItem (
303- onClick = onExportDebugLogs,
304- leadingContent = { MorpheIcon (icon = Icons .Outlined .Upload ) },
305- title = stringResource(R .string.settings_system_export_debug_logs),
306- description = stringResource(R .string.settings_system_export_debug_logs_description)
307- )
308- }
309- }
310-
311296 // Storage Management Section
312297 SectionTitle (
313298 text = stringResource(R .string.settings_system_storage_management),
@@ -414,6 +399,73 @@ fun SystemTabContent(
414399 }
415400}
416401
402+ /* *
403+ * A settings row with a title, optional description, and import/export action buttons.
404+ */
405+ @Composable
406+ private fun ImportExportRow (
407+ leadingContent : @Composable () -> Unit ,
408+ title : String ,
409+ description : String? = null,
410+ onImport : (() -> Unit )? ,
411+ onExport : (() -> Unit )?
412+ ) {
413+ val hasBoth = onImport != null && onExport != null
414+ Column (
415+ modifier = Modifier
416+ .fillMaxWidth()
417+ .padding(horizontal = 16 .dp, vertical = 12 .dp),
418+ verticalArrangement = Arrangement .spacedBy(10 .dp)
419+ ) {
420+ Row (
421+ horizontalArrangement = Arrangement .spacedBy(12 .dp),
422+ verticalAlignment = Alignment .CenterVertically
423+ ) {
424+ leadingContent()
425+ Column (modifier = Modifier .weight(1f )) {
426+ Text (
427+ text = title,
428+ style = MaterialTheme .typography.bodyMedium,
429+ fontWeight = FontWeight .Medium ,
430+ color = MaterialTheme .colorScheme.onSurface
431+ )
432+ if (description != null ) {
433+ Text (
434+ text = description,
435+ style = MaterialTheme .typography.bodySmall,
436+ color = MaterialTheme .colorScheme.onSurfaceVariant
437+ )
438+ }
439+ }
440+ }
441+ Row (
442+ modifier = Modifier .fillMaxWidth(),
443+ horizontalArrangement = if (hasBoth) Arrangement .spacedBy(8 .dp) else Arrangement .Center
444+ ) {
445+ if (onImport != null ) {
446+ ActionPillButton (
447+ onClick = onImport,
448+ icon = Icons .Outlined .Download ,
449+ contentDescription = stringResource(R .string.import_),
450+ modifier = if (hasBoth) Modifier .weight(1f ) else Modifier .fillMaxWidth(0.5f ),
451+ large = true ,
452+ label = stringResource(R .string.import_)
453+ )
454+ }
455+ if (onExport != null ) {
456+ ActionPillButton (
457+ onClick = onExport,
458+ icon = Icons .Outlined .Upload ,
459+ contentDescription = stringResource(R .string.export),
460+ modifier = if (hasBoth) Modifier .weight(1f ) else Modifier .fillMaxWidth(0.5f ),
461+ large = true ,
462+ label = stringResource(R .string.export)
463+ )
464+ }
465+ }
466+ }
467+ }
468+
417469/* * Maps a [BytecodeMode] to its short display label string resource. */
418470private fun BytecodeMode.labelRes (): Int = when (this ) {
419471 BytecodeMode .FULL -> R .string.settings_advanced_bytecode_mode_full
0 commit comments