mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 13:08:46 +00:00
Begin re-architecture of calling screen.
This commit is contained in:
16
core-ui/src/main/java/org/signal/core/ui/DarkPreview.kt
Normal file
16
core-ui/src/main/java/org/signal/core/ui/DarkPreview.kt
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.signal.core.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
||||
/**
|
||||
* Only generates a dark preview. Useful for screens that
|
||||
* are only ever rendered in dark mode (like calling)
|
||||
*/
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
annotation class DarkPreview()
|
||||
141
core-ui/src/main/java/org/signal/core/ui/IconButtons.kt
Normal file
141
core-ui/src/main/java/org/signal/core/ui/IconButtons.kt
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.signal.core.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.selection.toggleable
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.minimumInteractiveComponentSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.signal.core.ui.copied.androidx.compose.material3.IconButtonColors
|
||||
import org.signal.core.ui.copied.androidx.compose.material3.IconToggleButtonColors
|
||||
|
||||
object IconButtons {
|
||||
|
||||
@Composable
|
||||
fun iconButtonColors(
|
||||
containerColor: Color = Color.Transparent,
|
||||
contentColor: Color = LocalContentColor.current,
|
||||
disabledContainerColor: Color = Color.Transparent,
|
||||
disabledContentColor: Color =
|
||||
contentColor.copy(alpha = 0.38f)
|
||||
): IconButtonColors =
|
||||
IconButtonColors(
|
||||
containerColor = containerColor,
|
||||
contentColor = contentColor,
|
||||
disabledContainerColor = disabledContainerColor,
|
||||
disabledContentColor = disabledContentColor
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun iconToggleButtonColors(
|
||||
containerColor: Color = Color.Transparent,
|
||||
contentColor: Color = LocalContentColor.current,
|
||||
disabledContainerColor: Color = Color.Transparent,
|
||||
disabledContentColor: Color =
|
||||
contentColor.copy(alpha = 0.38f),
|
||||
checkedContainerColor: Color = Color.Transparent,
|
||||
checkedContentColor: Color = MaterialTheme.colorScheme.primary
|
||||
): IconToggleButtonColors =
|
||||
IconToggleButtonColors(
|
||||
containerColor = containerColor,
|
||||
contentColor = contentColor,
|
||||
disabledContainerColor = disabledContainerColor,
|
||||
disabledContentColor = disabledContentColor,
|
||||
checkedContainerColor = checkedContainerColor,
|
||||
checkedContentColor = checkedContentColor
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun IconButton(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
size: Dp = 40.dp,
|
||||
shape: Shape = CircleShape,
|
||||
enabled: Boolean = true,
|
||||
colors: IconButtonColors = iconButtonColors(),
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.minimumInteractiveComponentSize()
|
||||
.size(size)
|
||||
.clip(shape)
|
||||
.background(color = colors.containerColor(enabled).value)
|
||||
.clickable(
|
||||
onClick = onClick,
|
||||
enabled = enabled,
|
||||
role = Role.Button,
|
||||
interactionSource = interactionSource,
|
||||
indication = rememberRipple(
|
||||
bounded = false,
|
||||
radius = size / 2
|
||||
)
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
val contentColor = colors.contentColor(enabled).value
|
||||
CompositionLocalProvider(LocalContentColor provides contentColor, content = content)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun IconToggleButton(
|
||||
checked: Boolean,
|
||||
onCheckedChange: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
size: Dp = 40.dp,
|
||||
shape: Shape = CircleShape,
|
||||
enabled: Boolean = true,
|
||||
colors: IconToggleButtonColors = iconToggleButtonColors(),
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
(
|
||||
Box(
|
||||
modifier = modifier
|
||||
.minimumInteractiveComponentSize()
|
||||
.size(size)
|
||||
.clip(shape)
|
||||
.background(color = colors.containerColor(enabled, checked).value)
|
||||
.toggleable(
|
||||
value = checked,
|
||||
onValueChange = onCheckedChange,
|
||||
enabled = enabled,
|
||||
role = Role.Checkbox,
|
||||
interactionSource = interactionSource,
|
||||
indication = androidx.compose.material.ripple.rememberRipple(
|
||||
bounded = false,
|
||||
radius = size / 2
|
||||
)
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
val contentColor = colors.contentColor(enabled, checked).value
|
||||
CompositionLocalProvider(LocalContentColor provides contentColor, content = content)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.signal.core.ui.copied.androidx.compose.material3
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
@Immutable
|
||||
class IconButtonColors internal constructor(
|
||||
private val containerColor: Color,
|
||||
private val contentColor: Color,
|
||||
private val disabledContainerColor: Color,
|
||||
private val disabledContentColor: Color
|
||||
) {
|
||||
/**
|
||||
* Represents the container color for this icon button, depending on [enabled].
|
||||
*
|
||||
* @param enabled whether the icon button is enabled
|
||||
*/
|
||||
@Composable
|
||||
internal fun containerColor(enabled: Boolean): State<Color> {
|
||||
return rememberUpdatedState(if (enabled) containerColor else disabledContainerColor)
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the content color for this icon button, depending on [enabled].
|
||||
*
|
||||
* @param enabled whether the icon button is enabled
|
||||
*/
|
||||
@Composable
|
||||
internal fun contentColor(enabled: Boolean): State<Color> {
|
||||
return rememberUpdatedState(if (enabled) contentColor else disabledContentColor)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || other !is IconButtonColors) return false
|
||||
|
||||
if (containerColor != other.containerColor) return false
|
||||
if (contentColor != other.contentColor) return false
|
||||
if (disabledContainerColor != other.disabledContainerColor) return false
|
||||
if (disabledContentColor != other.disabledContentColor) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = containerColor.hashCode()
|
||||
result = 31 * result + contentColor.hashCode()
|
||||
result = 31 * result + disabledContainerColor.hashCode()
|
||||
result = 31 * result + disabledContentColor.hashCode()
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
class IconToggleButtonColors internal constructor(
|
||||
private val containerColor: Color,
|
||||
private val contentColor: Color,
|
||||
private val disabledContainerColor: Color,
|
||||
private val disabledContentColor: Color,
|
||||
private val checkedContainerColor: Color,
|
||||
private val checkedContentColor: Color
|
||||
) {
|
||||
/**
|
||||
* Represents the container color for this icon button, depending on [enabled] and [checked].
|
||||
*
|
||||
* @param enabled whether the icon button is enabled
|
||||
* @param checked whether the icon button is checked
|
||||
*/
|
||||
@Composable
|
||||
internal fun containerColor(enabled: Boolean, checked: Boolean): State<Color> {
|
||||
val target = when {
|
||||
!enabled -> disabledContainerColor
|
||||
!checked -> containerColor
|
||||
else -> checkedContainerColor
|
||||
}
|
||||
return rememberUpdatedState(target)
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the content color for this icon button, depending on [enabled] and [checked].
|
||||
*
|
||||
* @param enabled whether the icon button is enabled
|
||||
* @param checked whether the icon button is checked
|
||||
*/
|
||||
@Composable
|
||||
internal fun contentColor(enabled: Boolean, checked: Boolean): State<Color> {
|
||||
val target = when {
|
||||
!enabled -> disabledContentColor
|
||||
!checked -> contentColor
|
||||
else -> checkedContentColor
|
||||
}
|
||||
return rememberUpdatedState(target)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || other !is IconToggleButtonColors) return false
|
||||
|
||||
if (containerColor != other.containerColor) return false
|
||||
if (contentColor != other.contentColor) return false
|
||||
if (disabledContainerColor != other.disabledContainerColor) return false
|
||||
if (disabledContentColor != other.disabledContentColor) return false
|
||||
if (checkedContainerColor != other.checkedContainerColor) return false
|
||||
if (checkedContentColor != other.checkedContentColor) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = containerColor.hashCode()
|
||||
result = 31 * result + contentColor.hashCode()
|
||||
result = 31 * result + disabledContainerColor.hashCode()
|
||||
result = 31 * result + disabledContentColor.hashCode()
|
||||
result = 31 * result + checkedContainerColor.hashCode()
|
||||
result = 31 * result + checkedContentColor.hashCode()
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user