Add pager indicator

This commit is contained in:
andrew 2023-07-03 13:00:11 +09:30
parent 1303979cdf
commit 1902d4755c
3 changed files with 56 additions and 32 deletions

View File

@ -164,10 +164,10 @@ dependencies {
implementation 'com.github.bumptech.glide:compose:1.0.0-alpha.1' implementation 'com.github.bumptech.glide:compose:1.0.0-alpha.1'
implementation 'androidx.compose.ui:ui:1.4.3' implementation 'androidx.compose.ui:ui:1.4.3'
implementation 'androidx.compose.ui:ui-tooling:1.4.3' implementation 'androidx.compose.ui:ui-tooling:1.4.3'
implementation "com.google.accompanist:accompanist-themeadapter-appcompat:0.30.1" 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.4.3" implementation "androidx.compose.runtime:runtime-livedata:1.4.3"
implementation 'androidx.compose.foundation:foundation-layout:1.5.0-alpha02' implementation 'androidx.compose.foundation:foundation-layout:1.5.0-alpha02'
implementation 'androidx.compose.material:material:1.5.0-alpha02' implementation 'androidx.compose.material:material:1.5.0-alpha02'
} }

View File

@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.conversation.v2
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -11,7 +10,6 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
@ -19,6 +17,7 @@ import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Card
import androidx.compose.material.Divider import androidx.compose.material.Divider
import androidx.compose.material.LocalTextStyle import androidx.compose.material.LocalTextStyle
import androidx.compose.material.Text import androidx.compose.material.Text
@ -55,9 +54,11 @@ import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.mms.Slide import org.thoughtcrime.securesms.mms.Slide
import org.thoughtcrime.securesms.ui.AppTheme import org.thoughtcrime.securesms.ui.AppTheme
import org.thoughtcrime.securesms.ui.Cell import org.thoughtcrime.securesms.ui.Cell
import org.thoughtcrime.securesms.ui.CellWithPadding import org.thoughtcrime.securesms.ui.CellNoMargin
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
import org.thoughtcrime.securesms.ui.ItemButton import org.thoughtcrime.securesms.ui.ItemButton
import org.thoughtcrime.securesms.ui.LocalExtraColors import org.thoughtcrime.securesms.ui.LocalExtraColors
import org.thoughtcrime.securesms.ui.SessionHorizontalPagerIndicator
import org.thoughtcrime.securesms.ui.colorDestructive import org.thoughtcrime.securesms.ui.colorDestructive
import org.thoughtcrime.securesms.ui.destructiveButtonColors import org.thoughtcrime.securesms.ui.destructiveButtonColors
import java.util.* import java.util.*
@ -181,7 +182,6 @@ class MessageDetailActivity: PassphraseRequiredActionBarActivity() {
data class MessageDetails( data class MessageDetails(
val attachments: List<Attachment> = emptyList(), val attachments: List<Attachment> = emptyList(),
// val fileDetails: List<TitledText>? = null,
val sent: TitledText? = null, val sent: TitledText? = null,
val received: TitledText? = null, val received: TitledText? = null,
val error: TitledText? = null, val error: TitledText? = null,
@ -200,13 +200,6 @@ class MessageDetailActivity: PassphraseRequiredActionBarActivity() {
MessageDetails( MessageDetails(
MessageDetails( MessageDetails(
attachments = listOf(), attachments = listOf(),
// fileDetails = listOf(
// TitledText("File Id:", "1237896548514214124235985214"),
// TitledText("File Type:", ".PNG"),
// TitledText("File Size:", "6mb"),
// TitledText("Resolution:", "550x550"),
// TitledText("Duration:", "N/A"),
// ),
sent = TitledText("Sent:", "6:12 AM Tue, 09/08/2022"), sent = TitledText("Sent:", "6:12 AM Tue, 09/08/2022"),
received = TitledText("Received:", "6:12 AM Tue, 09/08/2022"), received = TitledText("Received:", "6:12 AM Tue, 09/08/2022"),
error = TitledText("Error:", "Message failed to send"), error = TitledText("Error:", "Message failed to send"),
@ -215,10 +208,6 @@ class MessageDetailActivity: PassphraseRequiredActionBarActivity() {
) )
} }
@OptIn(
ExperimentalLayoutApi::class,
ExperimentalFoundationApi::class,
ExperimentalGlideComposeApi::class)
@Composable @Composable
fun MessageDetails( fun MessageDetails(
messageDetails: MessageDetails, messageDetails: MessageDetails,
@ -233,7 +222,7 @@ class MessageDetailActivity: PassphraseRequiredActionBarActivity() {
verticalArrangement = Arrangement.spacedBy(16.dp) verticalArrangement = Arrangement.spacedBy(16.dp)
) { ) {
Attachments(attachments) Attachments(attachments)
if (sent != null || received != null || senderInfo != null) CellWithPadding { if (sent != null || received != null || senderInfo != null) CellWithPaddingAndMargin {
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) { Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
sent?.let { titledText(it) } sent?.let { titledText(it) }
received?.let { titledText(it) } received?.let { titledText(it) }
@ -292,24 +281,35 @@ class MessageDetailActivity: PassphraseRequiredActionBarActivity() {
) )
@Composable @Composable
fun ImageAttachments(attachments: List<Attachment>) { fun ImageAttachments(attachments: List<Attachment>) {
val pagerState = rememberPagerState() val imageAttachments = attachments.filter { it.slide.hasImage() }
val pagerState = rememberPagerState {
imageAttachments.size
}
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) { Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
Cell { CellNoMargin {
val imageAttachments = attachments.filter { it.slide.hasImage() } Box {
HorizontalPager(state = pagerState, pageCount = imageAttachments.size) { i -> HorizontalPager(state = pagerState) { i ->
imageAttachments[i].slide.apply { imageAttachments[i].slide.apply {
GlideImage( GlideImage(
contentScale = ContentScale.Crop, contentScale = ContentScale.Crop,
modifier = Modifier.aspectRatio(1f), modifier = Modifier.aspectRatio(1f),
model = uri, model = uri,
contentDescription = fileName.orNull() ?: "image" contentDescription = fileName.orNull() ?: "image"
)
}
}
if (imageAttachments.size >= 2) {
SessionHorizontalPagerIndicator(
modifier = Modifier.align(Alignment.BottomCenter),
pagerState = pagerState,
pageCount = imageAttachments.size,
) )
} }
} }
} }
attachments[pagerState.currentPage].fileDetails.takeIf { it.isNotEmpty() }?.let { attachments[pagerState.currentPage].fileDetails.takeIf { it.isNotEmpty() }?.let {
CellWithPadding { CellWithPaddingAndMargin {
FlowRow( FlowRow(
verticalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp),
maxItemsInEachRow = 2 maxItemsInEachRow = 2

View File

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.ui package org.thoughtcrime.securesms.ui
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@ -8,6 +9,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ButtonColors import androidx.compose.material.ButtonColors
import androidx.compose.material.Card import androidx.compose.material.Card
@ -18,10 +20,12 @@ import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.google.accompanist.pager.HorizontalPagerIndicator
@Composable @Composable
fun ItemButton( fun ItemButton(
@ -53,20 +57,40 @@ fun ItemButton(
@Composable @Composable
fun Cell(content: @Composable () -> Unit) { fun Cell(content: @Composable () -> Unit) {
CellWithPadding(0.dp) { content() } CellWithPaddingAndMargin(0.dp) { content() }
}
@Composable
fun CellNoMargin(content: @Composable () -> Unit) {
CellWithPaddingAndMargin(0.dp, 0.dp) { content() }
} }
@Composable @Composable
fun CellWithPadding(padding: Dp = 24.dp, content: @Composable () -> Unit) { fun CellWithPaddingAndMargin(
padding: Dp = 24.dp,
margin: Dp = 32.dp,
content: @Composable () -> Unit
) {
Card( Card(
shape = RoundedCornerShape(16.dp), shape = RoundedCornerShape(16.dp),
elevation = 0.dp, elevation = 0.dp,
modifier = Modifier modifier = Modifier
.wrapContentHeight() .wrapContentHeight()
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 32.dp), .padding(horizontal = margin),
backgroundColor = LocalExtraColors.current.settingsBackground, backgroundColor = LocalExtraColors.current.settingsBackground,
// probably wrong // probably wrong
contentColor = MaterialTheme.colors.onSurface contentColor = MaterialTheme.colors.onSurface
) { Box(Modifier.padding(padding)) { content() } } ) { Box(Modifier.padding(padding)) { content() } }
} }
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun SessionHorizontalPagerIndicator(modifier: Modifier, pagerState: PagerState, pageCount: Int) {
Card(shape = RoundedCornerShape(50.dp),
backgroundColor = Color.Black.copy(alpha = 0.4f),
modifier = Modifier.padding(8.dp).then(modifier)) {
Box(modifier = Modifier.padding(8.dp)) {
HorizontalPagerIndicator(pagerState = pagerState, pageCount = pageCount)
}
}
}