Fix fading edge

This commit is contained in:
andrew 2023-08-27 00:12:20 +09:30
parent 71b2544c31
commit 7a705642a2
5 changed files with 94 additions and 50 deletions

View File

@ -166,14 +166,14 @@ dependencies {
testImplementation 'org.robolectric:shadows-multidex:4.4'
implementation 'com.github.bumptech.glide:compose:1.0.0-alpha.1'
implementation 'androidx.compose.ui:ui:1.5.0'
implementation 'androidx.compose.ui:ui-tooling:1.5.0'
implementation 'androidx.compose.ui:ui:1.4.3'
implementation 'androidx.compose.ui:ui-tooling:1.4.3'
implementation "com.google.accompanist:accompanist-themeadapter-appcompat:0.31.5-beta"
implementation "com.google.accompanist:accompanist-pager-indicators:0.31.5-beta"
implementation "androidx.compose.runtime:runtime-livedata:1.5.0"
implementation "androidx.compose.runtime:runtime-livedata:1.4.3"
implementation 'androidx.compose.foundation:foundation-layout:1.5.0'
implementation 'androidx.compose.material:material:1.5.0'
implementation 'androidx.compose.foundation:foundation-layout:1.4.3'
implementation 'androidx.compose.material:material:1.4.3'
}
def canonicalVersionCode = 354

View File

@ -4,11 +4,13 @@ import android.os.Bundle
import android.widget.Toast
import androidx.activity.viewModels
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
@ -16,6 +18,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
@ -29,8 +32,14 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ModifierLocalBeyondBoundsLayout
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
@ -48,11 +57,13 @@ import org.thoughtcrime.securesms.database.RecipientDatabase
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.ui.AppTheme
import org.thoughtcrime.securesms.ui.CellNoMargin
import org.thoughtcrime.securesms.ui.Divider
import org.thoughtcrime.securesms.ui.GetString
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
import javax.inject.Inject
import kotlin.math.min
@AndroidEntryPoint
class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
@ -189,18 +200,22 @@ fun DisappearingMessages(
modifier: Modifier = Modifier,
onSetClick: () -> Unit = {}
) {
val scrollState = rememberScrollState()
Column(modifier = modifier) {
Box(modifier = Modifier.weight(1f)) {
Column(
modifier = Modifier
.padding(horizontal = 32.dp)
.verticalScroll(rememberScrollState()),
.padding(bottom = 20.dp)
.verticalScroll(scrollState)
.fadingEdges(scrollState),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
state.cards.filter { it.options.isNotEmpty() }.forEach { OptionsCard(it) }
state.cards.filter { it.options.isNotEmpty() }.forEach {
OptionsCard(it)
}
}
Gradient(100.dp, modifier = Modifier.align(Alignment.BottomCenter))
}
OutlineButton(
@ -213,6 +228,43 @@ fun DisappearingMessages(
}
}
fun Modifier.fadingEdges(
scrollState: ScrollState,
topEdgeHeight: Dp = 0.dp,
bottomEdgeHeight: Dp = 20.dp
): Modifier = this.then(
Modifier
// adding layer fixes issue with blending gradient and content
.graphicsLayer { alpha = 0.99F }
.drawWithContent {
drawContent()
val topColors = listOf(Color.Transparent, Color.Black)
val topStartY = scrollState.value.toFloat()
val topGradientHeight = min(topEdgeHeight.toPx(), topStartY)
drawRect(
brush = Brush.verticalGradient(
colors = topColors,
startY = topStartY,
endY = topStartY + topGradientHeight
),
blendMode = BlendMode.DstIn
)
val bottomColors = listOf(Color.Black, Color.Transparent)
val bottomEndY = size.height - scrollState.maxValue + scrollState.value
val bottomGradientHeight = min(bottomEdgeHeight.toPx(), scrollState.maxValue.toFloat() - scrollState.value)
if (bottomGradientHeight != 0f) drawRect(
brush = Brush.verticalGradient(
colors = bottomColors,
startY = bottomEndY - bottomGradientHeight,
endY = bottomEndY
),
blendMode = BlendMode.DstIn
)
}
)
@Composable
fun OptionsCard(card: CardModel) {
Text(text = card.title())
@ -220,7 +272,8 @@ fun OptionsCard(card: CardModel) {
LazyColumn(
modifier = Modifier.heightIn(max = 5000.dp)
) {
items(card.options) {
itemsIndexed(card.options) { i, it ->
if (i != 0) Divider()
TitledRadioButton(it)
}
}
@ -233,13 +286,13 @@ fun Gradient(height: Dp, modifier: Modifier = Modifier) {
modifier = modifier
.fillMaxWidth()
.height(height)
.background(
brush = Brush.verticalGradient(
colors = listOf(Color.Transparent, MaterialTheme.colors.primary),
startY = 0f,
endY = height.value
)
)
// .background(
// brush = Brush.verticalGradient(
// colors = listOf(Color.Transparent, MaterialTheme.colors.primary),
// startY = 0f,
// endY = height.value
// )
// )
)
}

View File

@ -90,15 +90,15 @@ class ExpirationSettingsViewModel(
fun typeOption(
type: ExpiryType,
@StringRes title: Int,
@StringRes subtitle: Int,
// @StringRes contentDescription: Int
) = OptionModel(GetString(title), GetString(subtitle)) { setType(type) }
@StringRes subtitle: Int? = null,
@StringRes contentDescription: Int = title
) = OptionModel(GetString(title), subtitle?.let(::GetString)) { setType(type) }
private fun typeOptions() = listOf(
typeOption(ExpiryType.NONE, R.string.expiration_off, R.string.AccessibilityId_disable_disappearing_messages),
typeOption(ExpiryType.LEGACY, R.string.expiration_type_disappear_legacy, R.string.expiration_type_disappear_legacy_description),
typeOption(ExpiryType.AFTER_READ, R.string.expiration_type_disappear_after_read, R.string.expiration_type_disappear_after_read_description),
typeOption(ExpiryType.AFTER_SEND, R.string.expiration_type_disappear_after_send, R.string.expiration_type_disappear_after_send_description),
typeOption(ExpiryType.NONE, R.string.expiration_off, contentDescription = R.string.AccessibilityId_disable_disappearing_messages),
typeOption(ExpiryType.LEGACY, R.string.expiration_type_disappear_legacy, contentDescription = R.string.expiration_type_disappear_legacy_description),
typeOption(ExpiryType.AFTER_READ, R.string.expiration_type_disappear_after_read, contentDescription = R.string.expiration_type_disappear_after_read_description),
typeOption(ExpiryType.AFTER_SEND, R.string.expiration_type_disappear_after_send, contentDescription = R.string.expiration_type_disappear_after_send_description),
)
private fun setType(type: ExpiryType) {
@ -127,7 +127,7 @@ class ExpirationSettingsViewModel(
val afterSendTimes = listOf(5.minutes, 1.hours) + afterReadTimes
private fun noteToSelfOptions() = listOfNotNull(
typeOption(ExpiryType.NONE, R.string.arrays__off, R.string.arrays__off),
typeOption(ExpiryType.NONE, R.string.arrays__off),
noteToSelfOption(1.minutes, subtitle = "for testing purposes").takeIf { BuildConfig.DEBUG },
) + afterSendTimes.map(::noteToSelfOption)

View File

@ -1,33 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
android:orientation="vertical">
<RelativeLayout
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false">
android:background="?colorPrimary"
app:contentInsetStart="0dp"
app:subtitle="@string/activity_expiration_settings_subtitle"
app:subtitleTextAppearance="@style/TextAppearance.Session.ToolbarSubtitle"
app:title="@string/activity_expiration_settings_title" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorPrimary"
app:contentInsetStart="0dp"
app:subtitle="@string/activity_expiration_settings_subtitle"
app:subtitleTextAppearance="@style/TextAppearance.Session.ToolbarSubtitle"
app:title="@string/activity_expiration_settings_title" />
<androidx.compose.ui.platform.ComposeView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<androidx.compose.ui.platform.ComposeView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"/>
</RelativeLayout>
</ScrollView>
</LinearLayout>

View File

@ -57,6 +57,6 @@ allprojects {
project.ext {
androidMinimumSdkVersion = 23
androidTargetSdkVersion = 33
androidCompileSdkVersion = 34
androidCompileSdkVersion = 33
}
}