Skip to content

Commit 4579d34

Browse files
feat: Migrate account chooser to Composable/Flow
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
1 parent 5c6db67 commit 4579d34

6 files changed

Lines changed: 295 additions & 313 deletions

File tree

app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountShareToAdapter.kt

Lines changed: 0 additions & 60 deletions
This file was deleted.
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/*
2+
* Nextcloud Talk - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2021-2026 Andy Scherzinger <info@andy-scherzinger.de>
5+
* SPDX-FileCopyrightText: 2022 Marcel Hibbe <dev@mhibbe.de>
6+
* SPDX-FileCopyrightText: 2017 Mario Danic <mario@lovelyhq.com>
7+
* SPDX-License-Identifier: GPL-3.0-or-later
8+
*/
9+
package com.nextcloud.talk.ui.dialog
10+
11+
import android.content.res.Configuration
12+
import androidx.compose.foundation.clickable
13+
import androidx.compose.foundation.isSystemInDarkTheme
14+
import androidx.compose.foundation.layout.Column
15+
import androidx.compose.foundation.layout.Row
16+
import androidx.compose.foundation.layout.fillMaxWidth
17+
import androidx.compose.foundation.layout.height
18+
import androidx.compose.foundation.layout.padding
19+
import androidx.compose.foundation.layout.size
20+
import androidx.compose.foundation.lazy.LazyColumn
21+
import androidx.compose.foundation.lazy.items
22+
import androidx.compose.material3.Icon
23+
import androidx.compose.material3.MaterialTheme
24+
import androidx.compose.material3.Surface
25+
import androidx.compose.material3.Text
26+
import androidx.compose.material3.darkColorScheme
27+
import androidx.compose.material3.lightColorScheme
28+
import androidx.compose.runtime.Composable
29+
import androidx.compose.ui.Alignment
30+
import androidx.compose.ui.Modifier
31+
import androidx.compose.ui.platform.LocalContext
32+
import androidx.compose.ui.res.colorResource
33+
import androidx.compose.ui.res.painterResource
34+
import androidx.compose.ui.res.stringResource
35+
import androidx.compose.ui.text.style.TextOverflow
36+
import androidx.compose.ui.tooling.preview.Preview
37+
import androidx.compose.ui.unit.dp
38+
import androidx.core.net.toUri
39+
import coil.compose.AsyncImage
40+
import com.nextcloud.talk.R
41+
import com.nextcloud.talk.contacts.loadImage
42+
import com.nextcloud.talk.data.user.model.User
43+
import com.nextcloud.talk.utils.ApiUtils
44+
45+
@Composable
46+
fun ChooseAccountShareToContent(
47+
currentUser: User?,
48+
otherUsers: List<User>,
49+
onCurrentUserClick: () -> Unit,
50+
onOtherUserClick: (User) -> Unit
51+
) {
52+
Surface(
53+
color = MaterialTheme.colorScheme.surfaceContainerHigh,
54+
modifier = Modifier.fillMaxWidth()
55+
) {
56+
LazyColumn(
57+
modifier = Modifier.fillMaxWidth()
58+
) {
59+
currentUser?.let {
60+
stickyHeader {
61+
CurrentAccountRow(user = currentUser, onClick = onCurrentUserClick)
62+
}
63+
}
64+
items(otherUsers) { user ->
65+
OtherAccountRow(user = user, onClick = { onOtherUserClick(user) })
66+
}
67+
}
68+
}
69+
}
70+
71+
@Composable
72+
private fun CurrentAccountRow(user: User, onClick: () -> Unit) {
73+
val context = LocalContext.current
74+
Row(
75+
modifier = Modifier
76+
.fillMaxWidth()
77+
.height(72.dp)
78+
.padding(4.dp)
79+
.clickable { onClick() },
80+
verticalAlignment = Alignment.CenterVertically
81+
) {
82+
AsyncImage(
83+
model = loadImage(
84+
ApiUtils.getUrlForAvatar(user.baseUrl, user.userId, true),
85+
context,
86+
R.drawable.account_circle_48dp
87+
),
88+
contentDescription = stringResource(R.string.avatar),
89+
modifier = Modifier
90+
.padding(start = 12.dp)
91+
.size(48.dp)
92+
)
93+
Column(
94+
modifier = Modifier
95+
.padding(start = 8.dp)
96+
.weight(1f)
97+
) {
98+
Text(
99+
text = user.displayName ?: user.username ?: "",
100+
style = MaterialTheme.typography.bodyLarge,
101+
maxLines = 1,
102+
overflow = TextOverflow.Ellipsis
103+
)
104+
Text(
105+
text = user.baseUrl?.toUri()?.host ?: user.baseUrl ?: "",
106+
style = MaterialTheme.typography.bodyMedium,
107+
color = colorResource(R.color.textColorMaxContrast),
108+
maxLines = 1,
109+
overflow = TextOverflow.Ellipsis
110+
)
111+
}
112+
Icon(
113+
painter = painterResource(R.drawable.ic_check_circle),
114+
contentDescription = stringResource(R.string.nc_account_chooser_active_user),
115+
tint = MaterialTheme.colorScheme.primary,
116+
modifier = Modifier
117+
.padding(end = 10.dp)
118+
.size(32.dp)
119+
)
120+
}
121+
}
122+
123+
@Composable
124+
private fun OtherAccountRow(user: User, onClick: () -> Unit) {
125+
val context = LocalContext.current
126+
Row(
127+
modifier = Modifier
128+
.fillMaxWidth()
129+
.height(72.dp)
130+
.padding(4.dp)
131+
.clickable { onClick() },
132+
verticalAlignment = Alignment.CenterVertically
133+
) {
134+
AsyncImage(
135+
model = loadImage(
136+
ApiUtils.getUrlForAvatar(user.baseUrl, user.userId, true),
137+
context,
138+
R.drawable.account_circle_48dp
139+
),
140+
contentDescription = stringResource(R.string.avatar),
141+
modifier = Modifier
142+
.padding(start = 12.dp)
143+
.size(48.dp)
144+
)
145+
Column(
146+
modifier = Modifier
147+
.padding(start = 8.dp)
148+
.weight(1f)
149+
) {
150+
Text(
151+
text = user.displayName ?: user.username ?: "",
152+
style = MaterialTheme.typography.bodyLarge,
153+
maxLines = 1,
154+
overflow = TextOverflow.Ellipsis
155+
)
156+
Text(
157+
text = user.baseUrl?.toUri()?.host ?: user.baseUrl ?: "",
158+
style = MaterialTheme.typography.bodyMedium,
159+
color = colorResource(R.color.textColorMaxContrast),
160+
maxLines = 1,
161+
overflow = TextOverflow.Ellipsis
162+
)
163+
}
164+
}
165+
}
166+
167+
@Preview(name = "Light Mode", showBackground = true)
168+
@Preview(
169+
name = "Dark Mode",
170+
showBackground = true,
171+
uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL
172+
)
173+
@Preview(
174+
name = "R-t-L",
175+
showBackground = true,
176+
locale = "ar"
177+
)
178+
@Composable
179+
private fun ChooseAccountShareToContentPreview() {
180+
val sampleCurrentUser = User(
181+
userId = "alice",
182+
username = "alice",
183+
baseUrl = "https://cloud.example.com",
184+
displayName = "Alice Example"
185+
)
186+
val sampleOtherUsers = listOf(
187+
User(
188+
userId = "bob",
189+
username = "bob",
190+
baseUrl = "https://nextcloud.example.org",
191+
displayName = "Bob Smith"
192+
),
193+
User(
194+
userId = "carol",
195+
username = "carol",
196+
baseUrl = "https://nc.example.net",
197+
displayName = "Carol Jones"
198+
)
199+
)
200+
val colorScheme = if (isSystemInDarkTheme()) darkColorScheme() else lightColorScheme()
201+
MaterialTheme(colorScheme = colorScheme) {
202+
Surface {
203+
ChooseAccountShareToContent(
204+
currentUser = sampleCurrentUser,
205+
otherUsers = sampleOtherUsers,
206+
onCurrentUserClick = {},
207+
onOtherUserClick = {}
208+
)
209+
}
210+
}
211+
}

0 commit comments

Comments
 (0)