|
1 | 1 | package com.redmadrobot.debug.plugin.aboutapp.ui |
2 | 2 |
|
| 3 | +import android.content.ClipData |
| 4 | +import androidx.compose.foundation.clickable |
3 | 5 | import androidx.compose.foundation.layout.Arrangement |
4 | | -import androidx.compose.foundation.layout.Column |
5 | 6 | import androidx.compose.foundation.layout.PaddingValues |
6 | | -import androidx.compose.foundation.layout.defaultMinSize |
| 7 | +import androidx.compose.foundation.layout.Row |
7 | 8 | import androidx.compose.foundation.layout.fillMaxSize |
8 | 9 | import androidx.compose.foundation.layout.fillMaxWidth |
9 | 10 | import androidx.compose.foundation.layout.padding |
| 11 | +import androidx.compose.foundation.layout.systemBarsPadding |
10 | 12 | import androidx.compose.foundation.lazy.LazyColumn |
11 | 13 | import androidx.compose.foundation.lazy.items |
12 | | -import androidx.compose.material.Card |
13 | | -import androidx.compose.material.MaterialTheme |
14 | | -import androidx.compose.material.Text |
| 14 | +import androidx.compose.material3.Scaffold |
| 15 | +import androidx.compose.material3.SnackbarHost |
| 16 | +import androidx.compose.material3.SnackbarHostState |
| 17 | +import androidx.compose.material3.Text |
15 | 18 | import androidx.compose.runtime.Composable |
| 19 | +import androidx.compose.runtime.LaunchedEffect |
16 | 20 | import androidx.compose.runtime.collectAsState |
17 | 21 | import androidx.compose.runtime.getValue |
18 | 22 | import androidx.compose.runtime.remember |
| 23 | +import androidx.compose.ui.Alignment |
19 | 24 | import androidx.compose.ui.Modifier |
20 | | -import androidx.compose.ui.text.font.FontWeight |
| 25 | +import androidx.compose.ui.draw.clip |
| 26 | +import androidx.compose.ui.platform.ClipEntry |
| 27 | +import androidx.compose.ui.platform.Clipboard |
| 28 | +import androidx.compose.ui.platform.LocalClipboard |
| 29 | +import androidx.compose.ui.res.stringResource |
21 | 30 | import androidx.compose.ui.text.style.TextOverflow |
22 | | -import androidx.compose.ui.tooling.preview.Preview |
23 | 31 | import androidx.compose.ui.unit.dp |
24 | 32 | import com.redmadrobot.debug.core.extension.getPlugin |
25 | 33 | import com.redmadrobot.debug.core.extension.provideViewModel |
26 | 34 | import com.redmadrobot.debug.plugin.aboutapp.AboutAppPlugin |
27 | 35 | import com.redmadrobot.debug.plugin.aboutapp.AboutAppPluginContainer |
| 36 | +import com.redmadrobot.debug.plugin.aboutapp.R |
28 | 37 | import com.redmadrobot.debug.plugin.aboutapp.model.AboutAppInfo |
| 38 | +import com.redmadrobot.debug.uikit.theme.DebugPanelShapes |
| 39 | +import com.redmadrobot.debug.uikit.theme.DebugPanelTheme |
29 | 40 |
|
30 | 41 | @Composable |
31 | 42 | internal fun AboutAppScreen( |
32 | 43 | viewModel: AboutAppViewModel = provideViewModel { |
33 | 44 | getPlugin<AboutAppPlugin>() |
34 | 45 | .getContainer<AboutAppPluginContainer>() |
35 | 46 | .createAboutAppViewModel() |
36 | | - } |
| 47 | + }, |
37 | 48 | ) { |
38 | | - val state by viewModel.state.collectAsState() |
| 49 | + val snackbarHostState = remember { SnackbarHostState() } |
39 | 50 |
|
40 | | - AboutAppLayout(state = state) |
41 | | -} |
| 51 | + val state by viewModel.state.collectAsState() |
| 52 | + val clipboard = LocalClipboard.current |
42 | 53 |
|
43 | | -@Composable |
44 | | -private fun AboutAppLayout(state: AboutAppViewState) { |
45 | | - LazyColumn( |
46 | | - modifier = Modifier.fillMaxSize(), |
47 | | - verticalArrangement = Arrangement.spacedBy(space = 8.dp), |
48 | | - contentPadding = PaddingValues(all = 16.dp), |
49 | | - ) { |
50 | | - items(items = state.appInfoList, key = { it.id }) { item -> |
51 | | - AboutAppItem(item = item) |
| 54 | + LaunchedEffect(Unit) { |
| 55 | + viewModel.events.collect { event -> |
| 56 | + copyToClipboard(clipboard = clipboard, item = event.item) |
| 57 | + val message = event.message.format(event.item.title) |
| 58 | + snackbarHostState.showSnackbar(message = message) |
52 | 59 | } |
53 | 60 | } |
54 | | -} |
55 | 61 |
|
56 | | -@Composable |
57 | | -private fun AboutAppItem(item: AboutAppInfo, modifier: Modifier = Modifier) { |
58 | | - Card( |
59 | | - modifier = modifier |
60 | | - .fillMaxWidth() |
61 | | - .defaultMinSize(minHeight = 56.dp), |
62 | | - elevation = 4.dp |
63 | | - ) { |
64 | | - Column( |
| 62 | + Scaffold( |
| 63 | + containerColor = DebugPanelTheme.colors.background.primary, |
| 64 | + snackbarHost = { |
| 65 | + SnackbarHost( |
| 66 | + modifier = Modifier.systemBarsPadding(), |
| 67 | + hostState = snackbarHostState |
| 68 | + ) |
| 69 | + }, |
| 70 | + ) { paddingValues -> |
| 71 | + LazyColumn( |
65 | 72 | modifier = Modifier |
66 | | - .fillMaxWidth() |
67 | | - .padding(all = 16.dp), |
68 | | - verticalArrangement = Arrangement.spacedBy(space = 4.dp), |
| 73 | + .fillMaxSize() |
| 74 | + .padding(paddingValues = paddingValues), |
| 75 | + contentPadding = PaddingValues(vertical = 8.dp), |
69 | 76 | ) { |
70 | | - Text( |
71 | | - text = item.title, |
72 | | - style = MaterialTheme.typography.caption, |
73 | | - fontWeight = FontWeight.SemiBold, |
74 | | - color = MaterialTheme.colors.primary, |
75 | | - ) |
76 | | - Text( |
77 | | - text = item.value, |
78 | | - style = MaterialTheme.typography.body1, |
79 | | - color = MaterialTheme.colors.onSurface, |
80 | | - maxLines = 2, |
81 | | - overflow = TextOverflow.Ellipsis, |
82 | | - ) |
| 77 | + items(items = state.appInfoList, key = { it.id }) { item -> |
| 78 | + InfoRow( |
| 79 | + label = item.title, |
| 80 | + value = item.value, |
| 81 | + onClick = { message -> |
| 82 | + viewModel.onInfoItemClicked(message = message, item = item) |
| 83 | + }, |
| 84 | + ) |
| 85 | + } |
83 | 86 | } |
84 | 87 | } |
85 | 88 | } |
86 | 89 |
|
87 | | -@Preview(showBackground = true) |
88 | 90 | @Composable |
89 | | -private fun Preview() { |
90 | | - val previewTitle = "Версия" |
91 | | - val previewValue = "3,14" |
92 | | - val state = remember { |
93 | | - AboutAppViewState( |
94 | | - appInfoList = listOf( |
95 | | - AboutAppInfo(title = previewTitle, value = previewValue), |
96 | | - AboutAppInfo( |
97 | | - title = "Номер билда", |
98 | | - value = "fgkdfjgkdfgjdfkgjdfkjgkdfjgkdfjgkdfjgkdjgskdjgkdgfjdsfgjdsfgdsfgjdsfgdskjfgdsjkfgdjfgdsfg" |
99 | | - ), |
100 | | - AboutAppInfo(title = previewTitle, value = previewValue), |
101 | | - AboutAppInfo(title = previewTitle, value = previewValue), |
102 | | - AboutAppInfo(title = previewTitle, value = previewValue), |
103 | | - AboutAppInfo(title = previewTitle, value = previewValue), |
104 | | - AboutAppInfo(title = previewTitle, value = previewValue), |
105 | | - AboutAppInfo(title = previewTitle, value = previewValue), |
106 | | - AboutAppInfo(title = previewTitle, value = previewValue), |
107 | | - ) |
| 91 | +private fun InfoRow( |
| 92 | + label: String, |
| 93 | + value: String, |
| 94 | + onClick: (String) -> Unit, |
| 95 | + modifier: Modifier = Modifier |
| 96 | +) { |
| 97 | + val copiedMessage = stringResource(id = R.string.about_app_copied) |
| 98 | + |
| 99 | + Row( |
| 100 | + modifier = modifier |
| 101 | + .fillMaxWidth() |
| 102 | + .clip(shape = DebugPanelShapes.medium) |
| 103 | + .clickable(onClick = { onClick.invoke(copiedMessage) }) |
| 104 | + .padding(horizontal = 12.dp, vertical = 8.dp), |
| 105 | + verticalAlignment = Alignment.Top, |
| 106 | + horizontalArrangement = Arrangement.Center |
| 107 | + ) { |
| 108 | + Text( |
| 109 | + text = label.uppercase(), |
| 110 | + style = DebugPanelTheme.typography.labelMedium, |
| 111 | + color = DebugPanelTheme.colors.content.tertiary, |
| 112 | + modifier = Modifier.padding(end = 12.dp), |
| 113 | + ) |
| 114 | + Text( |
| 115 | + text = value, |
| 116 | + style = DebugPanelTheme.typography.bodySmall, |
| 117 | + color = DebugPanelTheme.colors.content.primary, |
| 118 | + modifier = Modifier.weight(weight = 1f), |
| 119 | + overflow = TextOverflow.Ellipsis, |
108 | 120 | ) |
109 | 121 | } |
| 122 | +} |
110 | 123 |
|
111 | | - MaterialTheme { |
112 | | - AboutAppLayout(state = state) |
113 | | - } |
| 124 | +private suspend fun copyToClipboard(clipboard: Clipboard, item: AboutAppInfo) { |
| 125 | + val clipData = ClipData.newPlainText(item.title, item.value) |
| 126 | + |
| 127 | + clipboard.setClipEntry(clipEntry = ClipEntry(clipData)) |
114 | 128 | } |
0 commit comments