Skip to content

Commit

Permalink
Merge pull request #291 from you-apps/contacts-page-redesign
Browse files Browse the repository at this point in the history
feat: contacts page redesign
  • Loading branch information
Bnyro authored Oct 6, 2023
2 parents 47060b3 + b3c75c4 commit 45f5c65
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.bnyro.contacts.ui.components.base

import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun LargeButtonWithIcon(
modifier: Modifier = Modifier,
imageVector: ImageVector,
text: String,
onClick: () -> Unit
) {
Button(
modifier = modifier,
onClick = onClick,
shape = RoundedCornerShape(50.dp)
) {
Row(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
modifier = Modifier.size(20.dp),
imageVector = imageVector,
contentDescription = text
)
Spacer(modifier = Modifier.width(10.dp))
Text(text = text, fontSize = 18.sp)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.bnyro.contacts.ui.components.base

import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun SmallButtonWithIcon(
modifier: Modifier = Modifier,
imageVector: ImageVector,
text: String,
onClick: () -> Unit
) {
OutlinedButton(
modifier = modifier,
onClick = onClick,
) {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Icon(
modifier = Modifier.size(16.dp).offset(x = (-4).dp),
imageVector = imageVector,
contentDescription = text
)
Spacer(modifier = Modifier.width(4.dp))
Text(text = text, fontSize = 14.sp)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.bnyro.contacts.ui.components.shapes

import androidx.compose.foundation.shape.CornerBasedShape
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.shape.ZeroCornerSize
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.unit.LayoutDirection
import kotlin.math.cos
import kotlin.math.sin

val curlyCornerShape = CurlyCornerShape()

class CurlyCornerShape(
private val amp: Double = 10.0,
private val count: Int = 8,
) : CornerBasedShape(
topStart = ZeroCornerSize,
topEnd = ZeroCornerSize,
bottomEnd = ZeroCornerSize,
bottomStart = ZeroCornerSize
) {

private fun sineCircleXYatAngle(
d1: Double,
d2: Double,
d3: Double,
d4: Double,
d5: Double,
i: Int,
): List<Double> = (i.toDouble() * d5).run {
listOf(
(sin(this) * d4 + d3) * cos(d5) + d1,
(sin(this) * d4 + d3) * sin(d5) + d2
)
}

override fun createOutline(
size: Size,
topStart: Float,
topEnd: Float,
bottomEnd: Float,
bottomStart: Float,
layoutDirection: LayoutDirection,
): Outline {
val d = 2.0
val r2: Double = size.width / d
var r13: Double = size.height / d
val r18 = size.width / 2.0 - amp
val path = Path()
path.moveTo((d * r2 - amp).toFloat(), r13.toFloat())
var i = 0
while (true) {
val i2 = i + 1
val d3 = r13
val r5: List<Double> = sineCircleXYatAngle(
r2, r13, r18, amp, Math.toRadians(
i.toDouble()
), count
)
path.lineTo(r5[0].toFloat(), r5[1].toFloat())
if (i2 >= 360) {
path.close()
return Outline.Generic(path)
}
i = i2
r13 = d3
}
}

override fun copy(
topStart: CornerSize,
topEnd: CornerSize,
bottomEnd: CornerSize,
bottomStart: CornerSize,
) = RoundedCornerShape(
topStart = topStart,
topEnd = topEnd,
bottomEnd = bottomEnd,
bottomStart = bottomStart
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package com.bnyro.contacts.ui.screens
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
Expand All @@ -19,6 +22,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.Button
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
Expand All @@ -38,6 +42,7 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
Expand All @@ -51,14 +56,17 @@ import com.bnyro.contacts.ui.components.ContactProfilePicture
import com.bnyro.contacts.ui.components.ShareDialog
import com.bnyro.contacts.ui.components.base.ClickableIcon
import com.bnyro.contacts.ui.components.base.FullScreenDialog
import com.bnyro.contacts.ui.components.base.LargeButtonWithIcon
import com.bnyro.contacts.ui.components.base.SmallButtonWithIcon
import com.bnyro.contacts.ui.components.dialogs.ConfirmationDialog
import com.bnyro.contacts.ui.components.dialogs.ShortcutDialog
import com.bnyro.contacts.ui.components.shapes.curlyCornerShape
import com.bnyro.contacts.ui.models.ContactsModel
import com.bnyro.contacts.util.CalendarUtils
import com.bnyro.contacts.util.ContactsHelper
import com.bnyro.contacts.util.IntentHelper

@OptIn(ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable
fun SingleContactScreen(contact: ContactData, onClose: () -> Unit) {
val viewModel: ContactsModel = viewModel()
Expand Down Expand Up @@ -99,6 +107,18 @@ fun SingleContactScreen(contact: ContactData, onClose: () -> Unit) {
) {
showShortcutDialog = true
}
ClickableIcon(
icon = Icons.Default.Edit,
contentDescription = R.string.edit
) {
showEditor = true
}
ClickableIcon(
icon = Icons.Default.Delete,
contentDescription = R.string.delete
) {
showDelete = true
}
}
)
}
Expand All @@ -119,9 +139,9 @@ fun SingleContactScreen(contact: ContactData, onClose: () -> Unit) {
) {
Box(
modifier = Modifier
.size(135.dp)
.size(240.dp)
.background(
shape = CircleShape,
shape = curlyCornerShape,
color = MaterialTheme.colorScheme.primary
)
) {
Expand All @@ -130,14 +150,15 @@ fun SingleContactScreen(contact: ContactData, onClose: () -> Unit) {
modifier = Modifier.align(Alignment.Center),
text = (contact.displayName?.firstOrNull() ?: "").toString(),
color = MaterialTheme.colorScheme.onPrimary,
fontSize = 65.sp,
fontWeight = FontWeight.Bold
fontSize = 100.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
)
} else {
Image(
modifier = Modifier
.fillMaxSize()
.clip(CircleShape)
.clip(curlyCornerShape)
.clickable {
showZoomablePhoto = true
},
Expand All @@ -147,65 +168,49 @@ fun SingleContactScreen(contact: ContactData, onClose: () -> Unit) {
)
}
}
Spacer(modifier = Modifier.height(20.dp))
Spacer(modifier = Modifier.height(50.dp))
Text(
text = contact.displayName.orEmpty(),
fontSize = 30.sp,
fontWeight = FontWeight.Bold
)
}

ElevatedCard(
modifier = Modifier
.padding(bottom = 20.dp)
.align(Alignment.CenterHorizontally),
shape = RoundedCornerShape(12.dp)
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Row(
modifier = Modifier.padding(vertical = 6.dp, horizontal = 15.dp)
modifier = Modifier.padding(vertical = 6.dp, horizontal = 15.dp),
horizontalArrangement = Arrangement.Center
) {
ClickableIcon(
icon = Icons.Default.Call,
contentDescription = R.string.dial
) {
IntentHelper.launchAction(
context,
IntentActionType.DIAL,
contact.numbers.firstOrNull()?.value ?: return@ClickableIcon
)
}
Spacer(modifier = Modifier.width(5.dp))
ClickableIcon(
icon = Icons.Default.Message,
contentDescription = R.string.message
SmallButtonWithIcon(
imageVector = Icons.Default.Message,
text = stringResource(R.string.message)
) {
IntentHelper.launchAction(
context,
IntentActionType.SMS,
contact.numbers.firstOrNull()?.value ?: return@ClickableIcon
contact.numbers.firstOrNull()?.value ?: return@SmallButtonWithIcon
)
}
Spacer(modifier = Modifier.width(5.dp))
ClickableIcon(
icon = Icons.Default.Share,
contentDescription = R.string.share
Spacer(modifier = Modifier.size(10.dp))
SmallButtonWithIcon(
imageVector = Icons.Default.Share,
text = stringResource(R.string.share)
) {
showShareDialog = true
}
Spacer(modifier = Modifier.width(5.dp))
ClickableIcon(
icon = Icons.Default.Edit,
contentDescription = R.string.edit
) {
showEditor = true
}
Spacer(modifier = Modifier.width(5.dp))
ClickableIcon(
icon = Icons.Default.Delete,
contentDescription = R.string.delete
) {
showDelete = true
}
}
Spacer(modifier = Modifier.size(10.dp))
LargeButtonWithIcon(
imageVector = Icons.Default.Call,
text = stringResource(R.string.dial)
) {
IntentHelper.launchAction(
context,
IntentActionType.DIAL,
contact.numbers.firstOrNull()?.value ?: return@LargeButtonWithIcon
)
}
}

Expand Down

0 comments on commit 45f5c65

Please sign in to comment.