55
66package org.thoughtcrime.securesms.recipients.ui.about
77
8+ import android.content.res.Configuration
89import androidx.compose.foundation.clickable
910import androidx.compose.foundation.layout.Box
1011import androidx.compose.foundation.layout.Column
@@ -26,7 +27,6 @@ import androidx.compose.ui.Alignment
2627import androidx.compose.ui.Modifier
2728import androidx.compose.ui.draw.clip
2829import androidx.compose.ui.graphics.painter.Painter
29- import androidx.compose.ui.platform.LocalContext
3030import androidx.compose.ui.res.painterResource
3131import androidx.compose.ui.res.pluralStringResource
3232import androidx.compose.ui.res.stringResource
@@ -38,6 +38,7 @@ import androidx.core.widget.TextViewCompat
3838import org.signal.core.ui.BottomSheets
3939import org.signal.core.ui.theme.SignalTheme
4040import org.signal.core.util.getParcelableCompat
41+ import org.signal.core.util.isNotNullOrBlank
4142import org.thoughtcrime.securesms.AvatarPreviewActivity
4243import org.thoughtcrime.securesms.R
4344import org.thoughtcrime.securesms.avatar.AvatarImage
@@ -81,11 +82,27 @@ class AboutSheet : ComposeBottomSheetDialogFragment() {
8182 override fun SheetContent () {
8283 val recipient by viewModel.recipient
8384 val groupsInCommonCount by viewModel.groupsInCommonCount
85+ val verified by viewModel.verified
8486
8587 if (recipient.isPresent) {
86- AboutSheetContent (
87- recipient = recipient.get(),
88- groupsInCommonCount = groupsInCommonCount,
88+ Content (
89+ model = AboutModel (
90+ isSelf = recipient.get().isSelf,
91+ hasAvatar = recipient.get().profileAvatarFileDetails.hasFile(),
92+ displayName = recipient.get().getDisplayName(requireContext()),
93+ shortName = recipient.get().getShortDisplayName(requireContext()),
94+ about = recipient.get().about,
95+ verified = verified,
96+ recipientForAvatar = recipient.get(),
97+ formattedE164 = if (recipient.get().hasE164() && recipient.get().shouldShowE164()) {
98+ PhoneNumberFormatter .get(requireContext()).prettyPrintFormat(recipient.get().requireE164())
99+ } else {
100+ null
101+ },
102+ groupsInCommon = groupsInCommonCount,
103+ profileSharing = recipient.get().isProfileSharing,
104+ systemContact = recipient.get().isSystemContact
105+ ),
89106 onClickSignalConnections = this ::openSignalConnectionsSheet,
90107 onAvatarClicked = this ::openProfilePhotoViewer
91108 )
@@ -102,25 +119,23 @@ class AboutSheet : ComposeBottomSheetDialogFragment() {
102119 }
103120}
104121
105- @Preview
106- @Composable
107- private fun AboutSheetContentPreview () {
108- SignalTheme {
109- Surface {
110- AboutSheetContent (
111- recipient = Recipient .UNKNOWN ,
112- groupsInCommonCount = 0 ,
113- onClickSignalConnections = {},
114- onAvatarClicked = {}
115- )
116- }
117- }
118- }
122+ private data class AboutModel (
123+ val isSelf : Boolean ,
124+ val displayName : String ,
125+ val shortName : String ,
126+ val about : String? ,
127+ val verified : Boolean ,
128+ val hasAvatar : Boolean ,
129+ val recipientForAvatar : Recipient ,
130+ val formattedE164 : String? ,
131+ val profileSharing : Boolean ,
132+ val systemContact : Boolean ,
133+ val groupsInCommon : Int
134+ )
119135
120136@Composable
121- private fun AboutSheetContent (
122- recipient : Recipient ,
123- groupsInCommonCount : Int ,
137+ private fun Content (
138+ model : AboutModel ,
124139 onClickSignalConnections : () -> Unit ,
125140 onAvatarClicked : () -> Unit
126141) {
@@ -131,8 +146,8 @@ private fun AboutSheetContent(
131146 BottomSheets .Handle (modifier = Modifier .padding(top = 6 .dp))
132147 }
133148
134- val avatarOnClick = remember(recipient.profileAvatarFileDetails.hasFile() ) {
135- if (recipient.profileAvatarFileDetails.hasFile() ) {
149+ val avatarOnClick = remember(model.hasAvatar ) {
150+ if (model.hasAvatar ) {
136151 onAvatarClicked
137152 } else {
138153 { }
@@ -141,7 +156,7 @@ private fun AboutSheetContent(
141156
142157 Column (horizontalAlignment = Alignment .CenterHorizontally ) {
143158 AvatarImage (
144- recipient = recipient ,
159+ recipient = model.recipientForAvatar ,
145160 modifier = Modifier
146161 .padding(top = 56 .dp)
147162 .size(240 .dp)
@@ -150,30 +165,27 @@ private fun AboutSheetContent(
150165 )
151166
152167 Text (
153- text = stringResource(id = if (recipient .isSelf) R .string.AboutSheet__you else R .string.AboutSheet__about ),
168+ text = stringResource(id = if (model .isSelf) R .string.AboutSheet__you else R .string.AboutSheet__about ),
154169 style = MaterialTheme .typography.headlineMedium,
155170 modifier = Modifier
156171 .fillMaxWidth()
157172 .padding(horizontal = 32 .dp)
158173 .padding(top = 20 .dp, bottom = 14 .dp)
159174 )
160175
161- val context = LocalContext .current
162- val displayName = remember(recipient) { recipient.getDisplayName(context) }
163-
164176 AboutRow (
165177 startIcon = painterResource(R .drawable.symbol_person_24),
166- text = displayName,
178+ text = model. displayName,
167179 modifier = Modifier .fillMaxWidth()
168180 )
169181
170- if (! recipient .about.isNullOrBlank ()) {
182+ if (model .about.isNotNullOrBlank ()) {
171183 AboutRow (
172184 startIcon = painterResource(R .drawable.symbol_edit_24),
173185 text = {
174186 Row {
175187 AndroidView (factory = ::EmojiTextView ) {
176- it.text = recipient.combinedAboutAndEmoji
188+ it.text = model.about
177189
178190 TextViewCompat .setTextAppearance(it, R .style.Signal_Text_BodyLarge )
179191 }
@@ -183,44 +195,55 @@ private fun AboutSheetContent(
183195 )
184196 }
185197
186- if (recipient.isProfileSharing) {
198+ if (model.verified) {
199+ AboutRow (
200+ startIcon = painterResource(id = R .drawable.check),
201+ text = stringResource(id = R .string.AboutSheet__verified ),
202+ modifier = Modifier .align(alignment = Alignment .Start ),
203+ onClick = onClickSignalConnections
204+ )
205+ }
206+
207+ if (model.profileSharing || model.systemContact) {
187208 AboutRow (
188209 startIcon = painterResource(id = R .drawable.symbol_connections_24),
189210 text = stringResource(id = R .string.AboutSheet__signal_connection ),
190211 endIcon = painterResource(id = R .drawable.symbol_chevron_right_compact_bold_16),
191212 modifier = Modifier .align(alignment = Alignment .Start ),
192213 onClick = onClickSignalConnections
193214 )
215+ } else {
216+ AboutRow (
217+ startIcon = painterResource(id = R .drawable.chat_x),
218+ text = stringResource(id = R .string.AboutSheet__no_direct_message , model.shortName),
219+ modifier = Modifier .align(alignment = Alignment .Start ),
220+ onClick = onClickSignalConnections
221+ )
194222 }
195223
196- val shortName = remember(recipient) { recipient.getShortDisplayName(context) }
197- if (recipient.isSystemContact) {
224+ if (model.systemContact) {
198225 AboutRow (
199226 startIcon = painterResource(id = R .drawable.symbol_person_circle_24),
200- text = stringResource(id = R .string.AboutSheet__s_is_in_your_system_contacts , shortName),
227+ text = stringResource(id = R .string.AboutSheet__s_is_in_your_system_contacts , model. shortName),
201228 modifier = Modifier .fillMaxWidth()
202229 )
203230 }
204231
205- if (recipient.e164.isPresent && recipient.shouldShowE164()) {
206- val e164 = remember(recipient.e164.get()) {
207- PhoneNumberFormatter .get(context).prettyPrintFormat(recipient.e164.get())
208- }
209-
232+ if (model.formattedE164.isNotNullOrBlank()) {
210233 AboutRow (
211234 startIcon = painterResource(R .drawable.symbol_phone_24),
212- text = e164 ,
235+ text = model.formattedE164 ,
213236 modifier = Modifier .fillMaxWidth()
214237 )
215238 }
216239
217- val groupsInCommonText = if (recipient.hasGroupsInCommon() ) {
218- pluralStringResource(id = R .plurals.AboutSheet__d_groups_in , groupsInCommonCount, groupsInCommonCount )
240+ val groupsInCommonText = if (model.groupsInCommon > 0 ) {
241+ pluralStringResource(id = R .plurals.AboutSheet__d_groups_in , model.groupsInCommon, model.groupsInCommon )
219242 } else {
220243 stringResource(id = R .string.AboutSheet__you_have_no_groups_in_common )
221244 }
222245
223- val groupsInCommonIcon = if (! recipient.isProfileSharing && groupsInCommonCount == 0 ) {
246+ val groupsInCommonIcon = if (! model.profileSharing && model.groupsInCommon == 0 ) {
224247 painterResource(R .drawable.symbol_error_circle_24)
225248 } else {
226249 painterResource(R .drawable.symbol_group_24)
@@ -236,20 +259,6 @@ private fun AboutSheetContent(
236259 }
237260}
238261
239- @Preview
240- @Composable
241- private fun AboutRowPreview () {
242- SignalTheme {
243- Surface {
244- AboutRow (
245- startIcon = painterResource(R .drawable.symbol_person_24),
246- text = " Maya Johnson" ,
247- endIcon = painterResource(id = R .drawable.symbol_chevron_right_compact_bold_16)
248- )
249- }
250- }
251- }
252-
253262@Composable
254263private fun AboutRow (
255264 startIcon : Painter ,
@@ -318,3 +327,126 @@ private fun AboutRow(
318327 }
319328 }
320329}
330+
331+ @Preview(name = " Light Theme" , group = " content" , uiMode = Configuration .UI_MODE_NIGHT_NO )
332+ @Preview(name = " Dark Theme" , group = " content" , uiMode = Configuration .UI_MODE_NIGHT_YES )
333+ @Composable
334+ private fun ContentPreviewDefault () {
335+ SignalTheme {
336+ Surface {
337+ Content (
338+ model = AboutModel (
339+ isSelf = false ,
340+ hasAvatar = true ,
341+ displayName = " Peter Parker" ,
342+ shortName = " Peter" ,
343+ about = " Photographer for the Daily Bugle." ,
344+ verified = true ,
345+ recipientForAvatar = Recipient .UNKNOWN ,
346+ formattedE164 = " (123) 456-7890" ,
347+ profileSharing = true ,
348+ systemContact = true ,
349+ groupsInCommon = 0
350+ ),
351+ onClickSignalConnections = {},
352+ onAvatarClicked = {}
353+ )
354+ }
355+ }
356+ }
357+
358+ @Preview(name = " Light Theme" , group = " content" , uiMode = Configuration .UI_MODE_NIGHT_NO )
359+ @Preview(name = " Dark Theme" , group = " content" , uiMode = Configuration .UI_MODE_NIGHT_YES )
360+ @Composable
361+ private fun ContentPreviewInContactsNotProfileSharing () {
362+ SignalTheme {
363+ Surface {
364+ Content (
365+ model = AboutModel (
366+ isSelf = false ,
367+ hasAvatar = true ,
368+ displayName = " Peter Parker" ,
369+ shortName = " Peter" ,
370+ about = " Photographer for the Daily Bugle." ,
371+ verified = false ,
372+ recipientForAvatar = Recipient .UNKNOWN ,
373+ formattedE164 = null ,
374+ profileSharing = false ,
375+ systemContact = true ,
376+ groupsInCommon = 3
377+ ),
378+ onClickSignalConnections = {},
379+ onAvatarClicked = {}
380+ )
381+ }
382+ }
383+ }
384+
385+ @Preview(name = " Light Theme" , group = " content" , uiMode = Configuration .UI_MODE_NIGHT_NO )
386+ @Preview(name = " Dark Theme" , group = " content" , uiMode = Configuration .UI_MODE_NIGHT_YES )
387+ @Composable
388+ private fun ContentPreviewGroupsInCommonNoE164 () {
389+ SignalTheme {
390+ Surface {
391+ Content (
392+ model = AboutModel (
393+ isSelf = false ,
394+ hasAvatar = true ,
395+ displayName = " Peter Parker" ,
396+ shortName = " Peter" ,
397+ about = " Photographer for the Daily Bugle." ,
398+ verified = false ,
399+ recipientForAvatar = Recipient .UNKNOWN ,
400+ formattedE164 = null ,
401+ profileSharing = true ,
402+ systemContact = false ,
403+ groupsInCommon = 3
404+ ),
405+ onClickSignalConnections = {},
406+ onAvatarClicked = {}
407+ )
408+ }
409+ }
410+ }
411+
412+ @Preview(name = " Light Theme" , group = " content" , uiMode = Configuration .UI_MODE_NIGHT_NO )
413+ @Preview(name = " Dark Theme" , group = " content" , uiMode = Configuration .UI_MODE_NIGHT_YES )
414+ @Composable
415+ private fun ContentPreviewNotAConnection () {
416+ SignalTheme {
417+ Surface {
418+ Content (
419+ model = AboutModel (
420+ isSelf = false ,
421+ hasAvatar = true ,
422+ displayName = " Peter Parker" ,
423+ shortName = " Peter" ,
424+ about = " Photographer for the Daily Bugle." ,
425+ verified = false ,
426+ recipientForAvatar = Recipient .UNKNOWN ,
427+ formattedE164 = null ,
428+ profileSharing = false ,
429+ systemContact = false ,
430+ groupsInCommon = 3
431+ ),
432+ onClickSignalConnections = {},
433+ onAvatarClicked = {}
434+ )
435+ }
436+ }
437+ }
438+
439+ @Preview(name = " Light Theme" , group = " about row" , uiMode = Configuration .UI_MODE_NIGHT_NO )
440+ @Preview(name = " Dark Theme" , group = " about row" , uiMode = Configuration .UI_MODE_NIGHT_YES )
441+ @Composable
442+ private fun AboutRowPreview () {
443+ SignalTheme {
444+ Surface {
445+ AboutRow (
446+ startIcon = painterResource(R .drawable.symbol_person_24),
447+ text = " Maya Johnson" ,
448+ endIcon = painterResource(id = R .drawable.symbol_chevron_right_compact_bold_16)
449+ )
450+ }
451+ }
452+ }
0 commit comments