Merge pull request #724 from vector-im/feature/bma/designIteration
Design iteration
This commit is contained in:
commit
00d8161bdc
363 changed files with 1502 additions and 977 deletions
2
.idea/dictionaries/shared.xml
generated
2
.idea/dictionaries/shared.xml
generated
|
|
@ -4,7 +4,9 @@
|
|||
<w>backstack</w>
|
||||
<w>homeserver</w>
|
||||
<w>kover</w>
|
||||
<w>measurables</w>
|
||||
<w>onboarding</w>
|
||||
<w>placeables</w>
|
||||
<w>showkase</w>
|
||||
<w>textfields</w>
|
||||
</words>
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<inset
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:drawable="@mipmap/ic_launcher_round"
|
||||
android:insetTop="80dp"
|
||||
android:insetRight="80dp"
|
||||
android:insetBottom="80dp"
|
||||
android:insetLeft="80dp" />
|
||||
20
app/src/main/res/drawable/transparent.xml
Normal file
20
app/src/main/res/drawable/transparent.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2023 New Vector Ltd
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<solid android:color="#00000000" />
|
||||
|
||||
</shape>
|
||||
|
|
@ -17,8 +17,8 @@
|
|||
<resources>
|
||||
|
||||
<style name="Theme.ElementX.Splash" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@color/black</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/splash_icon</item>
|
||||
<item name="windowSplashScreenBackground">@color/splashscreen_bg_dark</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/transparent</item>
|
||||
<item name="postSplashScreenTheme">@style/Theme.ElementX</item>
|
||||
</style>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 New Vector Ltd
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
|
@ -16,11 +15,8 @@
|
|||
-->
|
||||
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
<!-- Must be equal to DarkDesignTokens.colorThemeBg -->
|
||||
<color name="splashscreen_bg_dark">#FF101317</color>
|
||||
<!-- Must be equal to LightDesignTokens.colorThemeBg -->
|
||||
<color name="splashscreen_bg_light">#FFFFFFFF</color>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@
|
|||
-->
|
||||
|
||||
<resources>
|
||||
<style name="Theme.ElementX.Splash" parent="Theme.SplashScreen.IconBackground">
|
||||
<item name="windowSplashScreenBackground">@color/white</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/splash_icon</item>
|
||||
<style name="Theme.ElementX.Splash" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@color/splashscreen_bg_light</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/transparent</item>
|
||||
<item name="postSplashScreenTheme">@style/Theme.ElementX</item>
|
||||
</style>
|
||||
<style name="Theme.ElementX" parent="Theme.Material3.Light" />
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ import androidx.compose.material3.MaterialTheme
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
|
|
@ -50,14 +49,12 @@ import io.element.android.features.invitelist.impl.model.InviteSender
|
|||
import io.element.android.libraries.designsystem.ElementTextStyles
|
||||
import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.OutlinedButton
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.noFontPadding
|
||||
import io.element.android.libraries.designsystem.theme.roomListUnreadIndicator
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
private val minHeight = 72.dp
|
||||
|
|
@ -161,8 +158,7 @@ internal fun DefaultInviteSummaryRow(
|
|||
}
|
||||
}
|
||||
|
||||
val unreadIndicatorColor = if (invite.isNew) MaterialTheme.roomListUnreadIndicator() else Color.Transparent
|
||||
UnreadIndicatorAtom(color = unreadIndicatorColor)
|
||||
UnreadIndicatorAtom(isVisible = invite.isNew)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import androidx.compose.material.icons.outlined.AddReaction
|
|||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
|
|
@ -48,6 +47,7 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -86,8 +86,8 @@ fun ActionListView(
|
|||
onEmojiReactionClicked: (String, TimelineItem.Event) -> Unit,
|
||||
onCustomReactionClicked: (TimelineItem.Event) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
sheetState: SheetState = rememberModalBottomSheetState()
|
||||
) {
|
||||
val sheetState = rememberModalBottomSheetState()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val targetItem = (state.target as? ActionListState.Target.Success)?.event
|
||||
|
||||
|
|
@ -118,22 +118,21 @@ fun ActionListView(
|
|||
}
|
||||
|
||||
fun onDismiss() {
|
||||
sheetState.hide(coroutineScope) {
|
||||
state.eventSink(ActionListEvents.Clear)
|
||||
}
|
||||
state.eventSink(ActionListEvents.Clear)
|
||||
}
|
||||
|
||||
if (targetItem != null) {
|
||||
ModalBottomSheet(
|
||||
sheetState = sheetState,
|
||||
onDismissRequest = ::onDismiss,
|
||||
modifier = modifier,
|
||||
) {
|
||||
SheetContent(
|
||||
state = state,
|
||||
onActionClicked = ::onItemActionClicked,
|
||||
onEmojiReactionClicked = ::onEmojiReactionClicked,
|
||||
onCustomReactionClicked = ::onCustomReactionClicked,
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.padding(bottom = 32.dp)
|
||||
// .navigationBarsPadding() - FIXME after https://issuetracker.google.com/issues/275849044
|
||||
// .imePadding()
|
||||
|
|
@ -191,7 +190,7 @@ private fun SheetContent(
|
|||
},
|
||||
text = {
|
||||
Text(
|
||||
text = action.title,
|
||||
text = stringResource(id = action.titleRes),
|
||||
color = if (action.destructive) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -17,20 +17,22 @@
|
|||
package io.element.android.features.messages.impl.actionlist.model
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import io.element.android.libraries.designsystem.VectorIcons
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Immutable
|
||||
sealed class TimelineItemAction(
|
||||
val title: String,
|
||||
@StringRes val titleRes: Int,
|
||||
@DrawableRes val icon: Int,
|
||||
val destructive: Boolean = false
|
||||
) {
|
||||
object Forward : TimelineItemAction("Forward", VectorIcons.Forward)
|
||||
object Copy : TimelineItemAction("Copy", VectorIcons.Copy)
|
||||
object Redact : TimelineItemAction("Redact", VectorIcons.Delete, destructive = true)
|
||||
object Reply : TimelineItemAction("Reply", VectorIcons.Reply)
|
||||
object Edit : TimelineItemAction("Edit", VectorIcons.Edit)
|
||||
object Developer : TimelineItemAction("Developer", VectorIcons.DeveloperMode)
|
||||
object ReportContent : TimelineItemAction("Report content", VectorIcons.ReportContent, destructive = true)
|
||||
object Forward : TimelineItemAction(CommonStrings.action_forward, VectorIcons.Forward)
|
||||
object Copy : TimelineItemAction(CommonStrings.action_copy, VectorIcons.Copy)
|
||||
object Redact : TimelineItemAction(CommonStrings.action_remove, VectorIcons.Delete, destructive = true)
|
||||
object Reply : TimelineItemAction(CommonStrings.action_reply, VectorIcons.Reply)
|
||||
object Edit : TimelineItemAction(CommonStrings.action_edit, VectorIcons.Edit)
|
||||
object Developer : TimelineItemAction(CommonStrings.action_view_source, VectorIcons.DeveloperMode)
|
||||
object ReportContent : TimelineItemAction(CommonStrings.action_report_content, VectorIcons.ReportContent, destructive = true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
|||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.Surface
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.messageFromMeBackground
|
||||
import io.element.android.libraries.designsystem.theme.messageFromOtherBackground
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
private val BUBBLE_RADIUS = 12.dp
|
||||
|
|
@ -97,14 +99,11 @@ fun MessageEventBubble(
|
|||
}
|
||||
}
|
||||
|
||||
val backgroundBubbleColor = if (state.isHighlighted) {
|
||||
ElementTheme.legacyColors.messageHighlightedBackground
|
||||
// Ignore state.isHighlighted for now, we need a design decision on it.
|
||||
val backgroundBubbleColor = if (state.isMine) {
|
||||
ElementTheme.colors.messageFromMeBackground
|
||||
} else {
|
||||
if (state.isMine) {
|
||||
ElementTheme.legacyColors.messageFromMeBackground
|
||||
} else {
|
||||
ElementTheme.legacyColors.messageFromOtherBackground
|
||||
}
|
||||
ElementTheme.colors.messageFromOtherBackground
|
||||
}
|
||||
val bubbleShape = bubbleShape()
|
||||
Box(
|
||||
|
|
|
|||
|
|
@ -41,18 +41,15 @@ private val CORNER_RADIUS = 8.dp
|
|||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun MessageStateEventContainer(
|
||||
isHighlighted: Boolean,
|
||||
@Suppress("UNUSED_PARAMETER") isHighlighted: Boolean,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit = {},
|
||||
onLongClick: () -> Unit = {},
|
||||
content: @Composable () -> Unit = {},
|
||||
) {
|
||||
val backgroundColor = if (isHighlighted) {
|
||||
ElementTheme.legacyColors.messageHighlightedBackground
|
||||
} else {
|
||||
Color.Companion.Transparent
|
||||
}
|
||||
// Ignore isHighlighted for now, we need a design decision on it.
|
||||
val backgroundColor = Color.Transparent
|
||||
val shape = RoundedCornerShape(CORNER_RADIUS)
|
||||
Surface(
|
||||
modifier = modifier
|
||||
|
|
|
|||
|
|
@ -58,15 +58,19 @@ fun TimelineEventTimestampView(
|
|||
val hasMessageSendingFailed = event.sendState is EventSendState.SendingFailed
|
||||
val isMessageEdited = (event.content as? TimelineItemTextBasedContent)?.isEdited.orFalse()
|
||||
val tint = if (hasMessageSendingFailed) MaterialTheme.colorScheme.error else null
|
||||
val clickModifier = if (hasMessageSendingFailed) {
|
||||
Modifier.combinedClickable(
|
||||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
indication = rememberRipple(bounded = false),
|
||||
interactionSource = MutableInteractionSource()
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.combinedClickable(
|
||||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
enabled = true,
|
||||
indication = rememberRipple(bounded = false),
|
||||
interactionSource = MutableInteractionSource()
|
||||
)
|
||||
.then(clickModifier)
|
||||
.padding(start = 16.dp) // Add extra padding for touch target size
|
||||
.then(modifier),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.clipToBounds
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -59,7 +58,6 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent
|
||||
import io.element.android.libraries.designsystem.ElementTextStyles
|
||||
import io.element.android.libraries.designsystem.components.EqualWidthColumn
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
|
|
@ -71,6 +69,8 @@ import io.element.android.libraries.matrix.api.core.UserId
|
|||
import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.InReplyTo
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType
|
||||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnail
|
||||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo
|
||||
|
|
@ -268,7 +268,7 @@ private fun MessageEventBubbleContent(
|
|||
}
|
||||
} else {
|
||||
Box(modifier) {
|
||||
ContentView(modifier = contentModifier.padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp))
|
||||
ContentView(modifier = contentModifier)
|
||||
TimelineEventTimestampView(
|
||||
event = event,
|
||||
onClick = onTimestampClicked,
|
||||
|
|
@ -316,7 +316,11 @@ private fun MessageEventBubbleContent(
|
|||
val contentModifier = if (isMediaItem) {
|
||||
Modifier.clip(RoundedCornerShape(12.dp))
|
||||
} else {
|
||||
Modifier
|
||||
if (inReplyToDetails != null) {
|
||||
Modifier.padding(start = 12.dp, end = 12.dp, top = 0.dp, bottom = 8.dp)
|
||||
} else {
|
||||
Modifier.padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp)
|
||||
}
|
||||
}
|
||||
|
||||
ContentAndTimestampView(
|
||||
|
|
@ -363,20 +367,19 @@ private fun ReplyToContent(
|
|||
}
|
||||
Column(verticalArrangement = Arrangement.SpaceBetween) {
|
||||
Text(
|
||||
senderName,
|
||||
style = ElementTextStyles.Regular.caption2.copy(fontWeight = FontWeight.Medium),
|
||||
text = senderName,
|
||||
style = ElementTheme.typography.fontBodySmMedium,
|
||||
textAlign = TextAlign.Start,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
color = ElementTheme.materialColors.primary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = text.orEmpty(),
|
||||
style = ElementTextStyles.Regular.caption1,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
textAlign = TextAlign.Start,
|
||||
color = ElementTheme.legacyColors.placeholder,
|
||||
maxLines = 1,
|
||||
color = ElementTheme.materialColors.secondary,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
|
|
@ -455,6 +458,76 @@ private fun ContentToPreview() {
|
|||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemEventRowWithReplyLightPreview() =
|
||||
ElementPreviewLight { ContentToPreviewWithReply() }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemEventRowWithReplyDarkPreview() =
|
||||
ElementPreviewDark { ContentToPreviewWithReply() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreviewWithReply() {
|
||||
Column {
|
||||
sequenceOf(false, true).forEach {
|
||||
val replyContent = if(it) {
|
||||
// Short
|
||||
"Message which are being replied."
|
||||
} else {
|
||||
// Long, to test 2 lines and ellipsis)
|
||||
"Message which are being replied, and which was long enough to be displayed on two lines (only!)."
|
||||
}
|
||||
TimelineItemEventRow(
|
||||
event = aTimelineItemEvent(
|
||||
isMine = it,
|
||||
content = aTimelineItemTextContent().copy(
|
||||
body = "A long text which will be displayed on several lines and" +
|
||||
" hopefully can be manually adjusted to test different behaviors."
|
||||
),
|
||||
inReplyTo = aInReplyToReady(replyContent)
|
||||
),
|
||||
isHighlighted = false,
|
||||
onClick = {},
|
||||
onLongClick = {},
|
||||
onUserDataClick = {},
|
||||
inReplyToClick = {},
|
||||
onReactionClick = { _, _ -> },
|
||||
onTimestampClicked = {},
|
||||
)
|
||||
TimelineItemEventRow(
|
||||
event = aTimelineItemEvent(
|
||||
isMine = it,
|
||||
content = aTimelineItemImageContent().copy(
|
||||
aspectRatio = 5f
|
||||
),
|
||||
inReplyTo = aInReplyToReady(replyContent)
|
||||
),
|
||||
isHighlighted = false,
|
||||
onClick = {},
|
||||
onLongClick = {},
|
||||
onUserDataClick = {},
|
||||
inReplyToClick = {},
|
||||
onReactionClick = { _, _ -> },
|
||||
onTimestampClicked = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun aInReplyToReady(
|
||||
replyContent: String
|
||||
): InReplyTo.Ready {
|
||||
return InReplyTo.Ready(
|
||||
eventId = EventId("\$event"),
|
||||
content = MessageContent(replyContent, null, false, TextMessageType(replyContent, null)),
|
||||
senderId = UserId("@Sender:domain"),
|
||||
senderDisplayName = "Sender",
|
||||
senderAvatarUrl = null,
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun TimelineItemEventRowTimestampLightPreview(@PreviewParameter(TimelineItemEventForTimestampViewProvider::class) event: TimelineItem.Event) =
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package io.element.android.features.messages.impl.timeline.components
|
|||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -50,6 +51,7 @@ fun TimelineItemStateEventRow(
|
|||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp)
|
||||
.wrapContentHeight(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -38,9 +38,7 @@ fun CustomReactionBottomSheet(
|
|||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
fun onDismiss() {
|
||||
sheetState.hide(coroutineScope) {
|
||||
state.eventSink(CustomReactionEvents.UpdateSelectedEvent(null))
|
||||
}
|
||||
state.eventSink(CustomReactionEvents.UpdateSelectedEvent(null))
|
||||
}
|
||||
|
||||
fun onEmojiSelectedDismiss(emoji: Emoji) {
|
||||
|
|
|
|||
|
|
@ -51,3 +51,11 @@ fun TimelineItem.Event.toExtraPadding(): ExtraPadding {
|
|||
// A space and a few unbreakable spaces
|
||||
return ExtraPadding(" " + "\u00A0".repeat(strLen))
|
||||
}
|
||||
|
||||
fun ExtraPadding.strBigger(): String {
|
||||
return if (str.isEmpty()) {
|
||||
str
|
||||
} else {
|
||||
str + "\u00A0\u00A0\u00A0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ fun TimelineItemInformativeView(
|
|||
fontStyle = FontStyle.Italic,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
fontSize = 14.sp,
|
||||
text = text + extraPadding.str
|
||||
// Since the font size is smaller, add more space to extra padding, to not overlap with the timestamp
|
||||
text = text + extraPadding.strBigger()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.unit.sp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Surface
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
|
|
@ -49,15 +48,12 @@ private val CORNER_RADIUS = 8.dp
|
|||
fun GroupHeaderView(
|
||||
text: String,
|
||||
isExpanded: Boolean,
|
||||
isHighlighted: Boolean,
|
||||
@Suppress("UNUSED_PARAMETER") isHighlighted: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val backgroundColor = if (isHighlighted) {
|
||||
ElementTheme.legacyColors.messageHighlightedBackground
|
||||
} else {
|
||||
Color.Companion.Transparent
|
||||
}
|
||||
// Ignore isHighlighted for now, we need a design decision on it.
|
||||
val backgroundColor = Color.Companion.Transparent
|
||||
val shape = RoundedCornerShape(CORNER_RADIUS)
|
||||
|
||||
Box(
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
|||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.ListItemDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -40,6 +39,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
|||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.features.messages.impl.R
|
||||
import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@ import androidx.compose.material.icons.outlined.Lock
|
|||
import androidx.compose.material.icons.outlined.Person
|
||||
import androidx.compose.material.icons.outlined.PersonAddAlt
|
||||
import androidx.compose.material.icons.outlined.Share
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -70,6 +68,9 @@ import io.element.android.libraries.designsystem.components.preferences.Preferen
|
|||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.preview.LargeHeightPreview
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenu
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItemText
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.IconButton
|
||||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||
|
|
@ -192,12 +193,11 @@ internal fun RoomDetailsTopBar(
|
|||
Icon(Icons.Default.MoreVert, "")
|
||||
}
|
||||
DropdownMenu(
|
||||
modifier = Modifier.widthIn(200.dp),
|
||||
expanded = showMenu,
|
||||
onDismissRequest = { showMenu = false },
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(id = CommonStrings.action_edit)) },
|
||||
text = { DropdownMenuItemText(stringResource(id = CommonStrings.action_edit)) },
|
||||
onClick = {
|
||||
// Explicitly close the menu before handling the action, as otherwise it stays open during the
|
||||
// transition and renders really badly.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.roomlist.impl
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
fun InvitesEntryPointView(
|
||||
onInvitesClicked: () -> Unit,
|
||||
state: InvitesState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.clickable(role = Role.Button, onClick = onInvitesClicked)
|
||||
.padding(start = 24.dp, end = 16.dp)
|
||||
.align(Alignment.CenterEnd)
|
||||
.heightIn(min = 40.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(CommonStrings.action_invites_list),
|
||||
style = ElementTheme.typography.fontBodyMdMedium,
|
||||
)
|
||||
|
||||
if (state == InvitesState.NewInvites) {
|
||||
Spacer(Modifier.width(8.dp))
|
||||
UnreadIndicatorAtom()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun InvitesEntryPointViewLightPreview(@PreviewParameter(InvitesStateProvider::class) state: InvitesState) =
|
||||
ElementPreviewLight { ContentToPreview(state) }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun InvitesEntryPointViewDarkPreview(@PreviewParameter(InvitesStateProvider::class) state: InvitesState) =
|
||||
ElementPreviewDark { ContentToPreview(state) }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview(state: InvitesState) {
|
||||
InvitesEntryPointView(
|
||||
onInvitesClicked = {},
|
||||
state = state,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.roomlist.impl
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
||||
open class InvitesStateProvider : PreviewParameterProvider<InvitesState> {
|
||||
override val values: Sequence<InvitesState>
|
||||
get() = sequenceOf(
|
||||
InvitesState.SeenInvites,
|
||||
InvitesState.NewInvites,
|
||||
)
|
||||
}
|
||||
|
|
@ -17,18 +17,12 @@
|
|||
package io.element.android.features.roomlist.impl
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
|
|
@ -42,17 +36,14 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.Velocity
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomView
|
||||
import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorView
|
||||
import io.element.android.features.roomlist.impl.components.RequestVerificationHeader
|
||||
|
|
@ -61,18 +52,15 @@ import io.element.android.features.roomlist.impl.components.RoomListTopBar
|
|||
import io.element.android.features.roomlist.impl.components.RoomSummaryRow
|
||||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
|
||||
import io.element.android.features.roomlist.impl.search.RoomListSearchResultView
|
||||
import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.Divider
|
||||
import io.element.android.libraries.designsystem.theme.components.FloatingActionButton
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.utils.LogCompositions
|
||||
import io.element.android.libraries.designsystem.utils.rememberSnackbarHostState
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.libraries.designsystem.R as DrawableR
|
||||
|
||||
@Composable
|
||||
|
|
@ -206,7 +194,7 @@ fun RoomListContent(
|
|||
|
||||
if (state.invitesState != InvitesState.NoInvites) {
|
||||
item {
|
||||
InvitesEntryPointView(onInvitesClicked, state)
|
||||
InvitesEntryPointView(onInvitesClicked, state.invitesState)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -251,38 +239,6 @@ fun RoomListContent(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun InvitesEntryPointView(
|
||||
onInvitesClicked: () -> Unit,
|
||||
state: RoomListState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clickable(role = Role.Button, onClick = onInvitesClicked)
|
||||
.padding(horizontal = 16.dp)
|
||||
.align(Alignment.CenterEnd)
|
||||
.heightIn(min = 48.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(CommonStrings.action_invites_list),
|
||||
fontSize = 14.sp,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
|
||||
if (state.invitesState == InvitesState.NewInvites) {
|
||||
Spacer(Modifier.width(8.dp))
|
||||
|
||||
UnreadIndicatorAtom()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun RoomListRoomSummary.contentType() = isPlaceholder
|
||||
|
||||
@Preview
|
||||
|
|
|
|||
|
|
@ -19,12 +19,10 @@ package io.element.android.features.roomlist.impl.components
|
|||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.BugReport
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material.icons.filled.Share
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material.icons.outlined.BugReport
|
||||
import androidx.compose.material.icons.outlined.Share
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
|
|
@ -48,6 +46,9 @@ import io.element.android.libraries.designsystem.components.avatar.Avatar
|
|||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenu
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItemText
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.IconButton
|
||||
import io.element.android.libraries.designsystem.theme.components.MediumTopAppBar
|
||||
|
|
@ -58,6 +59,7 @@ import io.element.android.libraries.matrix.api.user.MatrixUser
|
|||
import io.element.android.libraries.matrix.ui.model.getAvatarData
|
||||
import io.element.android.libraries.testtags.TestTags
|
||||
import io.element.android.libraries.testtags.testTag
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
|
|
@ -137,12 +139,20 @@ private fun DefaultRoomListTopBar(
|
|||
IconButton(
|
||||
onClick = onSearchClicked,
|
||||
) {
|
||||
Icon(Icons.Default.Search, contentDescription = stringResource(CommonStrings.action_search))
|
||||
Icon(
|
||||
imageVector = Icons.Default.Search,
|
||||
tint = ElementTheme.materialColors.secondary,
|
||||
contentDescription = stringResource(CommonStrings.action_search),
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = { showMenu = !showMenu }
|
||||
) {
|
||||
Icon(Icons.Default.MoreVert, contentDescription = null)
|
||||
Icon(
|
||||
imageVector = Icons.Default.MoreVert,
|
||||
tint = ElementTheme.materialColors.secondary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = showMenu,
|
||||
|
|
@ -153,16 +163,28 @@ private fun DefaultRoomListTopBar(
|
|||
showMenu = false
|
||||
onMenuActionClicked(RoomListMenuAction.InviteFriends)
|
||||
},
|
||||
text = { Text(stringResource(id = CommonStrings.action_invite)) },
|
||||
leadingIcon = { Icon(Icons.Default.Share, contentDescription = null) }
|
||||
text = { DropdownMenuItemText(stringResource(id = CommonStrings.action_invite)) },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
Icons.Outlined.Share,
|
||||
tint = ElementTheme.materialColors.secondary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
)
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
showMenu = false
|
||||
onMenuActionClicked(RoomListMenuAction.ReportBug)
|
||||
},
|
||||
text = { Text(stringResource(id = CommonStrings.common_report_a_bug)) },
|
||||
leadingIcon = { Icon(Icons.Default.BugReport, contentDescription = null) }
|
||||
text = { DropdownMenuItemText(stringResource(id = CommonStrings.common_report_a_bug)) },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
Icons.Outlined.BugReport,
|
||||
tint = ElementTheme.materialColors.secondary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import io.element.android.libraries.designsystem.atomic.atoms.PlaceholderAtom
|
|||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.roomListPlaceholder
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
/**
|
||||
|
|
@ -55,7 +56,7 @@ internal fun RoomSummaryPlaceholderRow(
|
|||
modifier = Modifier
|
||||
.size(AvatarSize.RoomListItem.dp)
|
||||
.align(Alignment.CenterVertically)
|
||||
.background(color = ElementTheme.colors.textPlaceholder, shape = CircleShape)
|
||||
.background(color = ElementTheme.colors.roomListPlaceholder, shape = CircleShape)
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -35,19 +35,16 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Outline
|
||||
import androidx.compose.ui.graphics.Path
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
|
||||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryProvider
|
||||
import io.element.android.libraries.core.extensions.orEmpty
|
||||
|
|
@ -59,7 +56,8 @@ import io.element.android.libraries.designsystem.theme.components.Text
|
|||
import io.element.android.libraries.designsystem.theme.roomListRoomMessage
|
||||
import io.element.android.libraries.designsystem.theme.roomListRoomMessageDate
|
||||
import io.element.android.libraries.designsystem.theme.roomListRoomName
|
||||
import io.element.android.libraries.designsystem.theme.roomListUnreadIndicator
|
||||
import io.element.android.libraries.designsystem.theme.unreadIndicator
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
internal val minHeight = 84.dp
|
||||
|
||||
|
|
@ -136,9 +134,7 @@ private fun RowScope.NameAndTimestampRow(room: RoomListRoomSummary) {
|
|||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(end = 16.dp),
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
style = ElementTheme.typography.fontBodyLgMedium,
|
||||
text = room.name,
|
||||
color = MaterialTheme.roomListRoomName(),
|
||||
maxLines = 1,
|
||||
|
|
@ -146,9 +142,13 @@ private fun RowScope.NameAndTimestampRow(room: RoomListRoomSummary) {
|
|||
)
|
||||
// Timestamp
|
||||
Text(
|
||||
fontSize = 12.sp,
|
||||
text = room.timestamp ?: "",
|
||||
color = MaterialTheme.roomListRoomMessageDate(),
|
||||
style = ElementTheme.typography.fontBodySmRegular,
|
||||
color = if (room.hasUnread) {
|
||||
ElementTheme.colors.unreadIndicator
|
||||
} else {
|
||||
MaterialTheme.roomListRoomMessageDate()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -163,17 +163,15 @@ private fun RowScope.LastMessageAndIndicatorRow(room: RoomListRoomSummary) {
|
|||
.padding(end = 28.dp),
|
||||
text = attributedLastMessage,
|
||||
color = MaterialTheme.roomListRoomMessage(),
|
||||
fontSize = 14.sp,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
minLines = 2,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
// Unread
|
||||
val unreadIndicatorColor =
|
||||
if (room.hasUnread) MaterialTheme.roomListUnreadIndicator() else Color.Transparent
|
||||
UnreadIndicatorAtom(
|
||||
modifier = Modifier.padding(top = 3.dp),
|
||||
color = unreadIndicatorColor,
|
||||
isVisible = room.hasUnread,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ internal fun RoomListSearchResultContent(
|
|||
.fillMaxWidth()
|
||||
.focusRequester(focusRequester),
|
||||
value = filter,
|
||||
singleLine = true,
|
||||
onValueChange = { state.eventSink(RoomListEvents.UpdateFilter(it)) },
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import androidx.compose.ui.unit.Dp
|
|||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.roomListPlaceholder
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
@Composable
|
||||
|
|
@ -36,7 +37,7 @@ fun PlaceholderAtom(
|
|||
width: Dp,
|
||||
height: Dp,
|
||||
modifier: Modifier = Modifier,
|
||||
color: Color = ElementTheme.colors.textPlaceholder,
|
||||
color: Color = ElementTheme.colors.roomListPlaceholder,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import androidx.compose.foundation.background
|
|||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -30,19 +29,21 @@ import androidx.compose.ui.unit.Dp
|
|||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.roomListUnreadIndicator
|
||||
import io.element.android.libraries.designsystem.theme.unreadIndicator
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
@Composable
|
||||
fun UnreadIndicatorAtom(
|
||||
modifier: Modifier = Modifier,
|
||||
size: Dp = 12.dp,
|
||||
color: Color = MaterialTheme.roomListUnreadIndicator(),
|
||||
color: Color = ElementTheme.colors.unreadIndicator,
|
||||
isVisible: Boolean = true,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(size)
|
||||
.clip(CircleShape)
|
||||
.background(color)
|
||||
.background(if (isVisible) color else Color.Transparent)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
/**
|
||||
* @param modifier Classical modifier.
|
||||
|
|
@ -87,7 +87,7 @@ private fun ContentToPreview() {
|
|||
) {
|
||||
Text(
|
||||
text = "Content",
|
||||
fontSize = 40.sp
|
||||
style = ElementTheme.typography.fontHeadingXlBold
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
@ -99,7 +99,7 @@ private fun ContentToPreview() {
|
|||
) {
|
||||
Text(
|
||||
text = "Header",
|
||||
fontSize = 40.sp
|
||||
style = ElementTheme.typography.fontHeadingXlBold
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
@ -111,7 +111,7 @@ private fun ContentToPreview() {
|
|||
) {
|
||||
Text(
|
||||
text = "Footer",
|
||||
fontSize = 40.sp
|
||||
style = ElementTheme.typography.fontHeadingXlBold
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,11 +30,11 @@ import androidx.compose.ui.layout.ContentScale
|
|||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import io.element.android.libraries.designsystem.R
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
/**
|
||||
* Page for onboarding screens, with content and optional footer.
|
||||
|
|
@ -106,7 +106,7 @@ private fun ContentToPreview() {
|
|||
) {
|
||||
Text(
|
||||
text = "Content",
|
||||
fontSize = 40.sp
|
||||
style = ElementTheme.typography.fontHeadingXlBold
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
@ -118,7 +118,7 @@ private fun ContentToPreview() {
|
|||
) {
|
||||
Text(
|
||||
text = "Footer",
|
||||
fontSize = 40.sp
|
||||
style = ElementTheme.typography.fontHeadingXlBold
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -39,8 +37,7 @@ import io.element.android.libraries.designsystem.preview.PreviewGroup
|
|||
import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar
|
||||
import io.element.android.libraries.designsystem.text.toSp
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.theme.AvatarGradientEnd
|
||||
import io.element.android.libraries.theme.AvatarGradientStart
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import timber.log.Timber
|
||||
|
||||
@Composable
|
||||
|
|
@ -89,16 +86,10 @@ private fun InitialsAvatar(
|
|||
avatarData: AvatarData,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val initialsGradient = Brush.linearGradient(
|
||||
listOf(
|
||||
AvatarGradientStart,
|
||||
AvatarGradientEnd,
|
||||
),
|
||||
start = Offset(0.0f, 100f),
|
||||
end = Offset(100f, 0f)
|
||||
)
|
||||
// Use temporary color for default avatar background
|
||||
val avatarColor = ElementTheme.colors.bgActionPrimaryDisabled
|
||||
Box(
|
||||
modifier.background(brush = initialsGradient),
|
||||
modifier.background(color = avatarColor),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.ruler
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
|
||||
/**
|
||||
* Horizontal ruler is a debug composable that displays a horizontal ruler.
|
||||
* It can be used to display the horizontal ruler in the composable preview.
|
||||
*/
|
||||
@Composable
|
||||
fun HorizontalRuler(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val baseColor = Color.Magenta
|
||||
val alphaBaseColor = baseColor.copy(alpha = 0.2f)
|
||||
Row(modifier = modifier.fillMaxWidth()) {
|
||||
repeat(50) {
|
||||
HorizontalRulerItem(1.dp, alphaBaseColor)
|
||||
HorizontalRulerItem(2.dp, baseColor)
|
||||
HorizontalRulerItem(1.dp, alphaBaseColor)
|
||||
HorizontalRulerItem(2.dp, baseColor)
|
||||
HorizontalRulerItem(5.dp, alphaBaseColor)
|
||||
HorizontalRulerItem(2.dp, baseColor)
|
||||
HorizontalRulerItem(1.dp, alphaBaseColor)
|
||||
HorizontalRulerItem(2.dp, baseColor)
|
||||
HorizontalRulerItem(1.dp, alphaBaseColor)
|
||||
HorizontalRulerItem(10.dp, baseColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HorizontalRulerItem(height: Dp, color: Color) {
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.size(height = height, width = 1.dp)
|
||||
.background(color = color)
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun HorizontalRulerLightPreview() =
|
||||
ElementPreviewLight { ContentToPreview() }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun HorizontalRulerDarkPreview() =
|
||||
ElementPreviewDark { ContentToPreview() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
HorizontalRuler()
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.ruler
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
|
||||
/**
|
||||
* Vertical ruler is a debug composable that displays a vertical ruler.
|
||||
* It can be used to display the vertical ruler in the composable preview.
|
||||
*/
|
||||
@Composable
|
||||
fun VerticalRuler(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val baseColor = Color.Red
|
||||
val alphaBaseColor = baseColor.copy(alpha = 0.2f)
|
||||
Column(modifier = modifier.fillMaxHeight()) {
|
||||
repeat(50) {
|
||||
VerticalRulerItem(1.dp, alphaBaseColor)
|
||||
VerticalRulerItem(2.dp, baseColor)
|
||||
VerticalRulerItem(1.dp, alphaBaseColor)
|
||||
VerticalRulerItem(2.dp, baseColor)
|
||||
VerticalRulerItem(5.dp, alphaBaseColor)
|
||||
VerticalRulerItem(2.dp, baseColor)
|
||||
VerticalRulerItem(1.dp, alphaBaseColor)
|
||||
VerticalRulerItem(2.dp, baseColor)
|
||||
VerticalRulerItem(1.dp, alphaBaseColor)
|
||||
VerticalRulerItem(10.dp, baseColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun VerticalRulerItem(width: Dp, color: Color) {
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.size(height = 1.dp, width = width)
|
||||
.background(color = color)
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun VerticalRulerLightPreview() =
|
||||
ElementPreviewLight { ContentToPreview() }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun VerticalRulerDarkPreview() =
|
||||
ElementPreviewDark { ContentToPreview() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
VerticalRuler()
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.ruler
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.Layout
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.OutlinedButton
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
|
||||
/**
|
||||
* Debug tool to add a vertical and a horizontal ruler on top of the content.
|
||||
*/
|
||||
@Composable
|
||||
fun WithRulers(
|
||||
modifier: Modifier = Modifier,
|
||||
xRulersOffset: Dp = 0.dp,
|
||||
yRulersOffset: Dp = 0.dp,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
Layout(
|
||||
modifier = modifier,
|
||||
content = {
|
||||
content()
|
||||
VerticalRuler()
|
||||
HorizontalRuler()
|
||||
},
|
||||
measurePolicy = { measurables, constraints ->
|
||||
val placeables = measurables.map { it.measure(constraints) }
|
||||
// Use layout size of the first item (the content)
|
||||
layout(
|
||||
width = placeables.first().width,
|
||||
height = placeables.first().height
|
||||
) {
|
||||
placeables.forEachIndexed { index, placeable ->
|
||||
if (index == 0) {
|
||||
placeable.place(0, 0)
|
||||
} else {
|
||||
placeable.place(xRulersOffset.roundToPx(), yRulersOffset.roundToPx())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun WithRulerLightPreview() =
|
||||
ElementPreviewLight { ContentToPreview() }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun WithRulerDarkPreview() =
|
||||
ElementPreviewDark { ContentToPreview() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
WithRulers(xRulersOffset = 20.dp, yRulersOffset = 15.dp) {
|
||||
OutlinedButton(onClick = {}) {
|
||||
Text(text = "A Button with rulers on it!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,8 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.theme.compound.generated.SemanticColors
|
||||
import io.element.android.libraries.theme.previews.ColorListPreview
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
|
||||
|
|
@ -37,8 +39,31 @@ fun MaterialTheme.roomListRoomMessage() = colorScheme.secondary
|
|||
@Composable
|
||||
fun MaterialTheme.roomListRoomMessageDate() = colorScheme.secondary
|
||||
|
||||
@Composable
|
||||
fun MaterialTheme.roomListUnreadIndicator() = colorScheme.primary
|
||||
val SemanticColors.unreadIndicator
|
||||
get() = iconAccentTertiary
|
||||
|
||||
val SemanticColors.roomListPlaceholder
|
||||
get() = bgSubtleSecondary
|
||||
|
||||
// This color is not present in Semantic color, so put hard-coded value for now
|
||||
val SemanticColors.messageFromMeBackground
|
||||
get() = if (isLight) {
|
||||
// We want LightDesignTokens.colorGray400
|
||||
Color(0xFFE1E6EC)
|
||||
} else {
|
||||
// We want DarkDesignTokens.colorGray500
|
||||
Color(0xFF323539)
|
||||
}
|
||||
|
||||
// This color is not present in Semantic color, so put hard-coded value for now
|
||||
val SemanticColors.messageFromOtherBackground
|
||||
get() = if (isLight) {
|
||||
// We want LightDesignTokens.colorGray300
|
||||
Color(0xFFF0F2F5)
|
||||
} else {
|
||||
// We want DarkDesignTokens.colorGray400
|
||||
Color(0xFF26282D)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
|
|
@ -57,7 +82,10 @@ private fun ContentToPreview() {
|
|||
"roomListRoomName" to MaterialTheme.roomListRoomName(),
|
||||
"roomListRoomMessage" to MaterialTheme.roomListRoomMessage(),
|
||||
"roomListRoomMessageDate" to MaterialTheme.roomListRoomMessageDate(),
|
||||
"roomListUnreadIndicator" to MaterialTheme.roomListUnreadIndicator(),
|
||||
"unreadIndicator" to ElementTheme.colors.unreadIndicator,
|
||||
"roomListPlaceholder" to ElementTheme.colors.roomListPlaceholder,
|
||||
"messageFromMeBackground" to ElementTheme.colors.messageFromMeBackground,
|
||||
"messageFromOtherBackground" to ElementTheme.colors.messageFromOtherBackground,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,95 +18,6 @@ package io.element.android.libraries.designsystem.theme
|
|||
|
||||
import androidx.compose.ui.text.PlatformTextStyle
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.airbnb.android.showkase.annotation.ShowkaseTypography
|
||||
|
||||
/**
|
||||
* TODO Provide the typo to Material3 theme.
|
||||
*/
|
||||
@ShowkaseTypography(name = "H1", group = "Element")
|
||||
val h1Default: TextStyle = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 24.sp
|
||||
)
|
||||
|
||||
@ShowkaseTypography(name = "Body1", group = "Element")
|
||||
val body1Default: TextStyle = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp
|
||||
)
|
||||
|
||||
@ShowkaseTypography(name = "BodySmall", group = "Element")
|
||||
val bodySmallDefault: TextStyle = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
|
||||
@ShowkaseTypography(name = "bodyMedium", group = "Element")
|
||||
val bodyMediumDefault: TextStyle = TextStyle(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 18.sp
|
||||
)
|
||||
|
||||
@ShowkaseTypography(name = "Body Large", group = "Element")
|
||||
val bodyLargeDefault: TextStyle = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
|
||||
@ShowkaseTypography(name = "Headline Small", group = "Element")
|
||||
val headlineSmallDefault: TextStyle = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 24.sp,
|
||||
lineHeight = 30.sp,
|
||||
letterSpacing = 1.sp
|
||||
)
|
||||
|
||||
@ShowkaseTypography(name = "Headline Medium", group = "Element")
|
||||
val headlineMediumDefault: TextStyle = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 28.sp,
|
||||
lineHeight = 34.sp,
|
||||
letterSpacing = 1.sp
|
||||
)
|
||||
|
||||
@ShowkaseTypography(name = "Headline Large", group = "Element")
|
||||
val headlineLargeDefault: TextStyle = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 32.sp,
|
||||
lineHeight = 38.sp,
|
||||
letterSpacing = 1.sp
|
||||
)
|
||||
|
||||
@ShowkaseTypography(name = "titleSmall", group = "Element")
|
||||
val titleSmallDefault: TextStyle = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 20.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
|
||||
@ShowkaseTypography(name = "titleMedium", group = "Element")
|
||||
val titleMediumDefault: TextStyle = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 18.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
|
||||
// Temporary style for text that needs to be aligned without weird font padding issues. `includeFontPadding` will default to false in a future version of
|
||||
// compose, at which point this can be removed.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.theme.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.PopupProperties
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
private val minMenuWidth = 200.dp
|
||||
|
||||
@Composable
|
||||
fun DropdownMenu(
|
||||
expanded: Boolean,
|
||||
onDismissRequest: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
// By default add a 16.dp offset to the menu
|
||||
offset: DpOffset = DpOffset(x = 16.dp, y = 0.dp),
|
||||
properties: PopupProperties = PopupProperties(focusable = true),
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
) {
|
||||
val bgColor = if (ElementTheme.isLightTheme) {
|
||||
ElementTheme.materialColors.background
|
||||
} else {
|
||||
ElementTheme.colors.bgSubtlePrimary
|
||||
}
|
||||
androidx.compose.material3.DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = onDismissRequest,
|
||||
modifier = modifier
|
||||
.background(color = bgColor)
|
||||
.widthIn(min = minMenuWidth),
|
||||
offset = offset,
|
||||
properties = properties,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.theme.components
|
||||
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.BugReport
|
||||
import androidx.compose.material.icons.filled.Share
|
||||
import androidx.compose.material3.MenuDefaults
|
||||
import androidx.compose.material3.MenuItemColors
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
@Composable
|
||||
fun DropdownMenuItem(
|
||||
text: @Composable () -> Unit,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
leadingIcon: @Composable (() -> Unit)? = null,
|
||||
trailingIcon: @Composable (() -> Unit)? = null,
|
||||
enabled: Boolean = true,
|
||||
colors: MenuItemColors = MenuDefaults.itemColors(),
|
||||
contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
) {
|
||||
androidx.compose.material3.DropdownMenuItem(
|
||||
text = text,
|
||||
onClick = onClick,
|
||||
modifier = modifier,
|
||||
leadingIcon = leadingIcon,
|
||||
trailingIcon = trailingIcon,
|
||||
enabled = enabled,
|
||||
colors = colors,
|
||||
contentPadding = contentPadding,
|
||||
interactionSource = interactionSource
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DropdownMenuItemText(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
color = ElementTheme.materialColors.primary,
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
@Preview(group = PreviewGroup.Menus)
|
||||
@Composable
|
||||
internal fun DropdownMenuItemPreview() = ElementThemedPreview { ContentToPreview() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
DropdownMenuItem(
|
||||
text = { DropdownMenuItemText(text = "Item") },
|
||||
onClick = {},
|
||||
leadingIcon = { Icon(Icons.Default.BugReport, contentDescription = null) },
|
||||
trailingIcon = { Icon(Icons.Default.Share, contentDescription = null) },
|
||||
)
|
||||
}
|
||||
|
|
@ -56,13 +56,18 @@ fun Text(
|
|||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
color: Color = Color.Unspecified,
|
||||
// Will be removed, only style should be used
|
||||
fontSize: TextUnit = TextUnit.Unspecified,
|
||||
fontStyle: FontStyle? = null,
|
||||
// Will be removed, only style should be used
|
||||
fontWeight: FontWeight? = null,
|
||||
// Will be removed, only style should be used
|
||||
fontFamily: FontFamily? = null,
|
||||
// Will be removed, only style should be used
|
||||
letterSpacing: TextUnit = TextUnit.Unspecified,
|
||||
textDecoration: TextDecoration? = null,
|
||||
textAlign: TextAlign? = null,
|
||||
// Will be removed, only style should be used
|
||||
lineHeight: TextUnit = TextUnit.Unspecified,
|
||||
overflow: TextOverflow = TextOverflow.Clip,
|
||||
softWrap: Boolean = true,
|
||||
|
|
@ -97,13 +102,18 @@ fun Text(
|
|||
text: AnnotatedString,
|
||||
modifier: Modifier = Modifier,
|
||||
color: Color = Color.Unspecified,
|
||||
// Will be removed, only style should be used
|
||||
fontSize: TextUnit = TextUnit.Unspecified,
|
||||
fontStyle: FontStyle? = null,
|
||||
// Will be removed, only style should be used
|
||||
fontWeight: FontWeight? = null,
|
||||
// Will be removed, only style should be used
|
||||
fontFamily: FontFamily? = null,
|
||||
// Will be removed, only style should be used
|
||||
letterSpacing: TextUnit = TextUnit.Unspecified,
|
||||
textDecoration: TextDecoration? = null,
|
||||
textAlign: TextAlign? = null,
|
||||
// Will be removed, only style should be used
|
||||
lineHeight: TextUnit = TextUnit.Unspecified,
|
||||
overflow: TextOverflow = TextOverflow.Clip,
|
||||
softWrap: Boolean = true,
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ package io.element.android.libraries.designsystem.theme.components.previews
|
|||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowRight
|
||||
import androidx.compose.material.icons.filled.Favorite
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
|
@ -30,6 +28,9 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenu
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItemText
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
|
||||
|
|
@ -59,7 +60,7 @@ internal fun MenuPreview() {
|
|||
null
|
||||
}
|
||||
DropdownMenuItem(
|
||||
text = { Text(text = "Item $i") },
|
||||
text = { DropdownMenuItemText(text = "Item $i") },
|
||||
onClick = { isExpanded = false },
|
||||
leadingIcon = leadingIcon,
|
||||
trailingIcon = trailingIcon,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package io.element.android.libraries.textcomposer
|
||||
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
|
|
@ -44,11 +46,13 @@ import androidx.compose.material3.LocalContentColor
|
|||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
|
|
@ -58,9 +62,9 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
|
|
@ -81,8 +85,9 @@ import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo
|
|||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.coroutines.android.awaitFrame
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
fun TextComposer(
|
||||
composerText: String?,
|
||||
|
|
@ -106,21 +111,31 @@ fun TextComposer(
|
|||
AttachmentButton(onClick = onAddAttachment, modifier = Modifier.padding(vertical = 6.dp))
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
var lineCount by remember { mutableStateOf(0) }
|
||||
val roundedCorners = remember(lineCount, composerMode) {
|
||||
val roundedCornerSize = remember(lineCount, composerMode) {
|
||||
if (lineCount > 1 || composerMode is MessageComposerMode.Special) {
|
||||
RoundedCornerShape(20.dp)
|
||||
20.dp
|
||||
} else {
|
||||
RoundedCornerShape(28.dp)
|
||||
28.dp
|
||||
}
|
||||
}
|
||||
|
||||
val roundedCornerSizeState = animateDpAsState(
|
||||
targetValue = roundedCornerSize,
|
||||
animationSpec = tween(
|
||||
durationMillis = 100,
|
||||
)
|
||||
)
|
||||
val roundedCorners = RoundedCornerShape(roundedCornerSizeState.value)
|
||||
val minHeight = 42.dp
|
||||
val bgColor = ElementTheme.colors.bgSubtleSecondary
|
||||
// Change border color depending on focus
|
||||
var hasFocus by remember { mutableStateOf(false) }
|
||||
val borderColor = if (hasFocus) ElementTheme.colors.borderDisabled else bgColor
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(roundedCorners)
|
||||
.background(MaterialTheme.colorScheme.surfaceVariant)
|
||||
.border(1.dp, MaterialTheme.colorScheme.outlineVariant, roundedCorners)
|
||||
.background(color = bgColor)
|
||||
.border(1.dp, borderColor, roundedCorners)
|
||||
) {
|
||||
if (composerMode is MessageComposerMode.Special) {
|
||||
ComposerModeView(composerMode = composerMode, onResetComposerMode = onResetComposerMode)
|
||||
|
|
@ -132,7 +147,10 @@ fun TextComposer(
|
|||
.fillMaxWidth()
|
||||
.heightIn(min = minHeight)
|
||||
.focusRequester(focusRequester)
|
||||
.onFocusEvent { onFocusChanged(it.hasFocus) },
|
||||
.onFocusEvent {
|
||||
hasFocus = it.hasFocus
|
||||
onFocusChanged(it.hasFocus)
|
||||
},
|
||||
value = text,
|
||||
onValueChange = { onComposerTextChange(it) },
|
||||
onTextLayout = {
|
||||
|
|
@ -156,16 +174,16 @@ fun TextComposer(
|
|||
colors = TextFieldDefaults.colors(
|
||||
unfocusedTextColor = MaterialTheme.colorScheme.secondary,
|
||||
focusedTextColor = MaterialTheme.colorScheme.primary,
|
||||
unfocusedPlaceholderColor = MaterialTheme.colorScheme.secondary,
|
||||
focusedPlaceholderColor = MaterialTheme.colorScheme.secondary,
|
||||
unfocusedPlaceholderColor = ElementTheme.colors.textDisabled,
|
||||
focusedPlaceholderColor = ElementTheme.colors.textDisabled,
|
||||
unfocusedIndicatorColor = Color.Transparent,
|
||||
focusedIndicatorColor = Color.Transparent,
|
||||
disabledIndicatorColor = Color.Transparent,
|
||||
errorIndicatorColor = Color.Transparent,
|
||||
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
errorContainerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
disabledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
unfocusedContainerColor = bgColor,
|
||||
focusedContainerColor = bgColor,
|
||||
errorContainerColor = bgColor,
|
||||
disabledContainerColor = bgColor,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -181,6 +199,18 @@ fun TextComposer(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Request focus when changing mode, and show keyboard.
|
||||
val keyboard = LocalSoftwareKeyboardController.current
|
||||
LaunchedEffect(composerMode) {
|
||||
if (composerMode is MessageComposerMode.Special) {
|
||||
focusRequester.requestFocus()
|
||||
keyboard?.let {
|
||||
awaitFrame()
|
||||
it.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -212,29 +242,35 @@ private fun EditingModeView(
|
|||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(5.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
.padding(start = 12.dp)
|
||||
) {
|
||||
Icon(
|
||||
resourceId = VectorIcons.Edit,
|
||||
contentDescription = stringResource(CommonStrings.common_editing),
|
||||
tint = MaterialTheme.colorScheme.secondary,
|
||||
modifier = Modifier.size(16.dp),
|
||||
tint = ElementTheme.materialColors.secondary,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 8.dp)
|
||||
.size(16.dp),
|
||||
)
|
||||
Text(
|
||||
stringResource(CommonStrings.common_editing),
|
||||
style = ElementTextStyles.Regular.caption2,
|
||||
style = ElementTheme.typography.fontBodySmRegular,
|
||||
textAlign = TextAlign.Start,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
modifier = Modifier.weight(1f)
|
||||
color = ElementTheme.materialColors.secondary,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 8.dp)
|
||||
.weight(1f)
|
||||
)
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = stringResource(CommonStrings.action_close),
|
||||
tint = MaterialTheme.colorScheme.secondary,
|
||||
tint = ElementTheme.materialColors.secondary,
|
||||
modifier = Modifier
|
||||
.padding(top = 8.dp, bottom = 8.dp, start = 16.dp, end = 12.dp)
|
||||
.size(16.dp)
|
||||
.clickable(
|
||||
enabled = true,
|
||||
|
|
@ -242,8 +278,7 @@ private fun EditingModeView(
|
|||
interactionSource = MutableInteractionSource(),
|
||||
indication = rememberRipple(bounded = false)
|
||||
),
|
||||
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -279,17 +314,16 @@ private fun ReplyToModeView(
|
|||
Text(
|
||||
text = senderName,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = ElementTextStyles.Regular.caption2.copy(fontWeight = FontWeight.Medium),
|
||||
style = ElementTheme.typography.fontBodySmMedium,
|
||||
textAlign = TextAlign.Start,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
color = ElementTheme.materialColors.primary,
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = text.orEmpty(),
|
||||
style = ElementTextStyles.Regular.caption1,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
textAlign = TextAlign.Start,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
color = ElementTheme.materialColors.secondary,
|
||||
maxLines = if (attachmentThumbnailInfo != null) 1 else 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
|
@ -316,24 +350,22 @@ private fun AttachmentButton(
|
|||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Box(modifier) {
|
||||
Surface(
|
||||
Modifier
|
||||
.size(30.dp)
|
||||
.clickable(true, onClick = onClick),
|
||||
shape = CircleShape,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier.size(12.5f.dp),
|
||||
painter = painterResource(R.drawable.ic_add_attachment),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.Inside,
|
||||
colorFilter = ColorFilter.tint(
|
||||
LocalContentColor.current
|
||||
)
|
||||
Surface(
|
||||
modifier
|
||||
.size(30.dp)
|
||||
.clickable(onClick = onClick),
|
||||
shape = CircleShape,
|
||||
color = ElementTheme.colors.iconPrimary
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier.size(12.5f.dp),
|
||||
painter = painterResource(R.drawable.ic_add_attachment),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.Inside,
|
||||
colorFilter = ColorFilter.tint(
|
||||
LocalContentColor.current
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -349,7 +381,7 @@ private fun BoxScope.SendButton(
|
|||
Box(
|
||||
modifier = modifier
|
||||
.clip(CircleShape)
|
||||
.background(if (canSendMessage) ElementTheme.legacyColors.accentColor else Color.Transparent)
|
||||
.background(if (canSendMessage) ElementTheme.colors.iconAccentTertiary else Color.Transparent)
|
||||
.size(30.dp)
|
||||
.align(Alignment.BottomEnd)
|
||||
.applyIf(composerMode !is MessageComposerMode.Edit, ifTrue = {
|
||||
|
|
@ -376,7 +408,8 @@ private fun BoxScope.SendButton(
|
|||
modifier = Modifier.size(16.dp),
|
||||
resourceId = iconId,
|
||||
contentDescription = contentDescription,
|
||||
tint = if (canSendMessage) Color.White else ElementTheme.legacyColors.quaternary
|
||||
// Exception here, we use Color.White instead of ElementTheme.colors.iconOnSolidPrimary
|
||||
tint = if (canSendMessage) Color.White else ElementTheme.colors.iconDisabled
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,9 +37,6 @@ import io.element.android.libraries.theme.compound.generated.SemanticColors
|
|||
@Deprecated("Use SemanticColors instead")
|
||||
@Stable
|
||||
class ElementColors(
|
||||
messageFromMeBackground: Color,
|
||||
messageFromOtherBackground: Color,
|
||||
messageHighlightedBackground: Color,
|
||||
quaternary: Color,
|
||||
quinary: Color,
|
||||
gray300: Color,
|
||||
|
|
@ -47,13 +44,6 @@ class ElementColors(
|
|||
placeholder: Color,
|
||||
isLight: Boolean
|
||||
) {
|
||||
var messageFromMeBackground by mutableStateOf(messageFromMeBackground)
|
||||
private set
|
||||
var messageFromOtherBackground by mutableStateOf(messageFromOtherBackground)
|
||||
private set
|
||||
var messageHighlightedBackground by mutableStateOf(messageHighlightedBackground)
|
||||
private set
|
||||
|
||||
var quaternary by mutableStateOf(quaternary)
|
||||
private set
|
||||
|
||||
|
|
@ -73,9 +63,6 @@ class ElementColors(
|
|||
private set
|
||||
|
||||
fun copy(
|
||||
messageFromMeBackground: Color = this.messageFromMeBackground,
|
||||
messageFromOtherBackground: Color = this.messageFromOtherBackground,
|
||||
messageHighlightedBackground: Color = this.messageHighlightedBackground,
|
||||
quaternary: Color = this.quaternary,
|
||||
quinary: Color = this.quinary,
|
||||
gray300: Color = this.gray300,
|
||||
|
|
@ -83,9 +70,6 @@ class ElementColors(
|
|||
placeholder: Color = this.placeholder,
|
||||
isLight: Boolean = this.isLight,
|
||||
) = ElementColors(
|
||||
messageFromMeBackground = messageFromMeBackground,
|
||||
messageFromOtherBackground = messageFromOtherBackground,
|
||||
messageHighlightedBackground = messageHighlightedBackground,
|
||||
quaternary = quaternary,
|
||||
quinary = quinary,
|
||||
gray300 = gray300,
|
||||
|
|
@ -95,9 +79,6 @@ class ElementColors(
|
|||
)
|
||||
|
||||
fun updateColorsFrom(other: ElementColors) {
|
||||
messageFromMeBackground = other.messageFromMeBackground
|
||||
messageFromOtherBackground = other.messageFromOtherBackground
|
||||
messageHighlightedBackground = other.messageHighlightedBackground
|
||||
quaternary = other.quaternary
|
||||
quinary = other.quinary
|
||||
gray300 = other.gray300
|
||||
|
|
@ -108,9 +89,6 @@ class ElementColors(
|
|||
}
|
||||
|
||||
internal fun elementColorsLight() = ElementColors(
|
||||
messageFromMeBackground = SystemGrey5Light,
|
||||
messageFromOtherBackground = SystemGrey6Light,
|
||||
messageHighlightedBackground = Azure,
|
||||
quaternary = Gray_100,
|
||||
quinary = Gray_50,
|
||||
gray300 = LightDesignTokens.colorGray300,
|
||||
|
|
@ -120,9 +98,6 @@ internal fun elementColorsLight() = ElementColors(
|
|||
)
|
||||
|
||||
internal fun elementColorsDark() = ElementColors(
|
||||
messageFromMeBackground = SystemGrey5Dark,
|
||||
messageFromOtherBackground = SystemGrey6Dark,
|
||||
messageHighlightedBackground = Azure,
|
||||
quaternary = Gray_400,
|
||||
quinary = Gray_450,
|
||||
gray300 = DarkDesignTokens.colorGray300,
|
||||
|
|
|
|||
|
|
@ -32,9 +32,6 @@ val LightGrey = Color(0x993C3C43)
|
|||
@ShowkaseColor(name = "DarkGrey", group = "Material Design")
|
||||
val DarkGrey = Color(0x99EBEBF5)
|
||||
|
||||
val AvatarGradientStart = Color(0xFF4CA1AF)
|
||||
val AvatarGradientEnd = Color(0xFFC4E0E5)
|
||||
|
||||
val SystemGreyLight = Color(0xFF8E8E93)
|
||||
val SystemGreyDark = Color(0xFF8E8E93)
|
||||
val SystemGrey2Light = Color(0xFFAEAEB2)
|
||||
|
|
|
|||
|
|
@ -89,7 +89,8 @@ internal val compoundColorsDark = SemanticColors(
|
|||
textInfoPrimary = DarkDesignTokens.colorBlue900,
|
||||
textOnSolidPrimary = DarkDesignTokens.colorThemeBg,
|
||||
bgSubtlePrimary = DarkDesignTokens.colorGray400,
|
||||
bgSubtleSecondary = DarkDesignTokens.colorBgSubtleSecondaryLevel0,
|
||||
// The value DarkDesignTokens.colorBgSubtleSecondaryLevel0 is defined to colorThemeBg, this is not correct, so override the value here until this is fixed,
|
||||
bgSubtleSecondary = DarkDesignTokens.colorGray300, // DarkDesignTokens.colorBgSubtleSecondaryLevel0
|
||||
bgCanvasDefault = DarkDesignTokens.colorBgCanvasDefaultLevel1,
|
||||
bgCanvasDisabled = DarkDesignTokens.colorGray200,
|
||||
bgActionPrimaryRest = DarkDesignTokens.colorGray1400,
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b890e242878fde4f516b0cd7e18a27144c8f45751e78b9e4b71df25f960d3c23
|
||||
size 7346
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8d9439b1152f64883f840c3d6dc24860dfc60443b664f8cc1f13e61e2107468e
|
||||
size 6178
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:998406b633aee537e05c16a0bcdf99f2ca6eb0c10be56e47e628bc5fe28f7cf4
|
||||
size 6911
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0e7194a4ec66200dd15b366b0164014c555011e588a57f16977520cfdad847e2
|
||||
size 4803
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1e2bd1ad9eeadd3f38bfc5dcf5757f34ab0e6d5fb6eb16797fac8ff4f852317f
|
||||
size 10221
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2582d7170cd8f73bd17a99330eaedbc99b0da499a6b4b83dd51d06a5634d7d7c
|
||||
size 10113
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fc761827658dd299df1214b34acef31ddd809126e386b67d2eb99a6c1805a1f9
|
||||
size 8563
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:660bd26dce3731d9fc7e694dfe863e1fdb89939b4dbf6526a3092eb0fc71bc47
|
||||
size 8032
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9322418313536b9bfc3e870ab5f3086473fc2abb465bebe9896e6a4c0a896f24
|
||||
size 7267
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f29698b6c7d924f2eb4a4b38679769dd62283bb927c62b2e2c3e5b2a9117c99a
|
||||
size 6364
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:14da396544c0accc0229fa249c43caa70d105482d34290edac22047891386ff7
|
||||
size 39928
|
||||
oid sha256:db05c9dc303b03a8965e199981cb786491fcf814bf78244b3fc5b7e323807700
|
||||
size 28097
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:adabf8c147f6122a180db6f2b44fcd85b2b08ec6651acb7b3519e5a821045f4a
|
||||
size 39902
|
||||
oid sha256:bdb04dc4e9f047baa6209478c3083c80738e208938d2f25df282fb84dd3aecd0
|
||||
size 28855
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cc235fc17b0eaaacf1a2dc6ec4759372d29cd4ba0741f7f6f57a9bb9a460c806
|
||||
size 101302
|
||||
oid sha256:d8b15997a41e7ba655990243c5347aa87d59811a727b034a7b52e99b074e6648
|
||||
size 88860
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7a6baba1197b01eb91e2dc6720482b97d9d0cdd5aaffa0d19d3e6b0860dadcf8
|
||||
size 52502
|
||||
oid sha256:153fe6422f5248b250096a7ef51a2b89c970f47bca5a24d0938632d08f9e96e2
|
||||
size 46872
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3eddd53d1e02f314d219ad3c7a935149a973ecf47603a3dd0492053f0e174668
|
||||
size 35977
|
||||
oid sha256:e7642a1adb1faec60a301ee86bb34558ea71d15f4fbd3d5ddd5d1661249b725a
|
||||
size 25759
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9db3469badeb7f71b5f9cb6df6b230158f8d383e48dae2b615e94b885b1f2145
|
||||
size 81076
|
||||
oid sha256:b0457439922b1990f6fd72449c6f4042b72755e09ab9f3c9c8a8c03c9fc925eb
|
||||
size 63888
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7ab609e664a3fb0f258b99414b799e591161876d348d1c35f03ece1a57d6dce1
|
||||
size 91478
|
||||
oid sha256:98c56ef886a3d1b6b3109bb835e587176f4e420bb05057dc150c82153605f7d1
|
||||
size 67794
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e00be325947e9ef638fdabd178b70da994a5b78f82ebfa199d469883b156e8bb
|
||||
size 35205
|
||||
oid sha256:f467065bb9c78d0e95a8a688bfc50edce522b2832c9a53e5a68899e843a988ca
|
||||
size 25859
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f85f0a3b5bb3edd6d864a2a211437a278f6bb7a9b66367a9ed4d596f673dc197
|
||||
size 80258
|
||||
oid sha256:a2ba6ed9981ea1ad3f0cdf76d600d6a51daf58a04f15c5bf23713c7f31e84b94
|
||||
size 65471
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8defc1027b2a97aeca89c7f969d458afbcbb4f0ed3e4474046e1242ceec8d80d
|
||||
size 90196
|
||||
oid sha256:c1f75b3ada8d9462a23b7defd26ac16562ff6ccf9babfcc7330286712ceb805e
|
||||
size 69581
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5847edfd77fe888d3da67fc27c72a9dd40b78ebede21483a48394ee5859197a7
|
||||
size 93560
|
||||
oid sha256:8d04e77e3a7e7862f29868be068df658382ed7dec94fcea86665bbd5074591bd
|
||||
size 82804
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1b42685b2852d5d45eee744a98dba74a5f26ddc1fb88960a7c23d4e335a75369
|
||||
size 95600
|
||||
oid sha256:4f8de89448ff5f4f95c7611657e38e0ba75c2f503b82fb04f584f3116353ae51
|
||||
size 85954
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8b275a7d15d76711cc2eaa00e819a573e50ddff699f82b2b0e65ec8489547732
|
||||
size 22163
|
||||
oid sha256:b2567be3b27bb2ea979b7da492fb059e87b25c5938c07aacaa621a97685bacd5
|
||||
size 21095
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5b7247bd672cf5a4ed121d65369c0825a01be379773ca696038eadf4f23269b7
|
||||
size 27606
|
||||
oid sha256:300883c3e49ff5e655952cf2b5a0a194718fde9c6fd289c3125e4cd3609cea00
|
||||
size 26379
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f6c09f5e6fb876196e5b6db3ea0f562a2ff04c48a5858a939f2765d41b1c4e13
|
||||
size 22314
|
||||
oid sha256:e80d2a64eb4c39e117dbd3bdd6b1b45b19a99f8e1ccb905547f82096fae8510d
|
||||
size 21465
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2eca0c7ce88cf3ccb13fc1a7f52c96922c417f8cfb951f25db91c20c1714771a
|
||||
size 28472
|
||||
oid sha256:1b91f0e2d72bf5b12430183ccb98cb30e1e0ab3859472c5a6368b5cca1ceb33c
|
||||
size 27574
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d4479241e4fc5c15ec6c2122d1eaafd9f2fe79a9235fd25f215f850e0b852f03
|
||||
size 31269
|
||||
oid sha256:4233e67a2f27e3e73924b9af5f43d0e877a397f4a2ee3f8d436a713e1d2b3c0c
|
||||
size 28738
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9ea5f4da6a888551e2e91a8b594fcc090cf806a56df315c5607abcb5e4f12495
|
||||
size 36839
|
||||
oid sha256:69b2702985d50fedbb720e86eef63c2734e328d8537c6a8f644fcf75c7e710a8
|
||||
size 32883
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0f58fe221866c9d199645ef71cc5d38aa1fef67e49f74bed5e042ae5ce1f3a5d
|
||||
size 36803
|
||||
oid sha256:76681a4959008b8646273424cd50566d7c868620938e07849da596ccd3172781
|
||||
size 33020
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:aa16a4c974eaee9e02b734db508ab04f4ff87ef6d22ae64d0841e63ad37967e3
|
||||
size 17760
|
||||
oid sha256:0052281199753556fd2d8ed411360ee15e5019e2ddd3ec2b1a9695c81be3a233
|
||||
size 14402
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b0601334a2e45adfd5488e99175156a0e14fdb83fcc292173812fd4232ccc528
|
||||
size 31374
|
||||
oid sha256:57878214b3949c4eaa782f763095e9e8234a979e0e7fe83fcf1e5083bfb32bf0
|
||||
size 28878
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c13288bd03da93cdbc6969ef4b9a0a317da9802a1b02ce41cf305b42146a1f46
|
||||
size 32673
|
||||
oid sha256:9482e9994ab5c2367d52811fa72559d9c1660e517b5d242e7d714f3e84ba03c5
|
||||
size 29271
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0457a0275d880dc738fb60ae9e53b3d1d7630592d2107a0dd03b3cb80685b0cc
|
||||
size 37881
|
||||
oid sha256:9bb46ebec6a9fbdab74f9634d1c834c52c1f690183b3b360e24c79012ed3a192
|
||||
size 34823
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e0ae1dba87aa070607268c0243f18301c7ebf0b23cebe91bc1b668eda9da0025
|
||||
size 37867
|
||||
oid sha256:fca36d620adf924e4c6605832dea8df4f2b87e7ac472c98a5ffae0056816be8a
|
||||
size 34944
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0bde7c2be2ae19012c6f8df9626bc0d912e2899239fe5527865980dbe02cfee7
|
||||
size 17384
|
||||
oid sha256:9b202f4160bdb58a9e87cfc66f11a5aaf66a90591c978dfc797b3cf351c94103
|
||||
size 14396
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:79a9749e15d3875d95602a325f6238ad666d7acfa9256d6865c1b6492ec74cdf
|
||||
size 32815
|
||||
oid sha256:afc363e9509019637ad9a7b4120462e1b2679d02a4b815c5840a83336cb9616a
|
||||
size 29654
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:30856dd6b233c75f387d9160ee3700c21e197f1a17b85da8b654042a1b88601c
|
||||
size 63741
|
||||
oid sha256:6ab4fab7980768994954a4089ff32116f28ec46f89ed30474ab45239d39f448c
|
||||
size 52948
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:466ef043bc10bc265c928e12464c0d42007dd3f15dbca8f7e352169754c58ee2
|
||||
size 46836
|
||||
oid sha256:20be7d313c5058ce7016ec573a9db05387df0dc4c41aab07200a2c3f55b35d55
|
||||
size 43832
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f3bfe2e04da74cb561dddb85cdb36c31ebee2e05ab96fc821bb7d26133826d52
|
||||
size 47264
|
||||
oid sha256:c6db133ab25a03de88c6153ce6adc58c834539b2c85e35c1438bb55cdb91abe5
|
||||
size 44271
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1657e4438b39cbf720e2ec0d488a40e841e9c2b518e4f663dfe7cde0f9c862c2
|
||||
size 42308
|
||||
oid sha256:bd2fd38fd3cf6eaa78de876cace7c614680108c3ed0eeb634ebaf9e004840f98
|
||||
size 37575
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1657e4438b39cbf720e2ec0d488a40e841e9c2b518e4f663dfe7cde0f9c862c2
|
||||
size 42308
|
||||
oid sha256:bd2fd38fd3cf6eaa78de876cace7c614680108c3ed0eeb634ebaf9e004840f98
|
||||
size 37575
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dae7690e7f01647a4711b3940ca15549fe7ecf9043dd6ef2066b144561398608
|
||||
size 64708
|
||||
oid sha256:04357ef36543729e5ed5794f3624194315080b9a5bc6024235a131e009e5a922
|
||||
size 55391
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4b1407a9001ed72fcc8bbedafcdc9233d9c3e2bc7996fd8a4e549c4e7f8d6e1d
|
||||
size 48179
|
||||
oid sha256:506d061e8004745bf7c1472d1a96702ef9b47e60e99839e7cab8f16071b88b1d
|
||||
size 45813
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:630eb1ea4c3979e6e6ad4fcc48eaea723798c85ffb703670566957e42385ae98
|
||||
size 48616
|
||||
oid sha256:3f58db0ddc56fc3e6178f4aafbdd0501a5bba129068420cab0c3b8cfadc33b50
|
||||
size 46244
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:66fc42a41b1e0c3abf2edb465f986f722d3558179bc3ebcbf0740e9bc794d62c
|
||||
size 43023
|
||||
oid sha256:289b4fb5dc4c0a27deec988f8810584162451c763760d1e9ee66da367f869c6e
|
||||
size 39173
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:66fc42a41b1e0c3abf2edb465f986f722d3558179bc3ebcbf0740e9bc794d62c
|
||||
size 43023
|
||||
oid sha256:289b4fb5dc4c0a27deec988f8810584162451c763760d1e9ee66da367f869c6e
|
||||
size 39173
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7c3a97e67ebd54d043dfb09c773ab74e927c48517ce07cd87452c69bb96cb228
|
||||
size 38498
|
||||
oid sha256:5ce2edea622636c3709d7da3d01c931a2ced65d31738d9cfc9e5f318a374ca30
|
||||
size 37850
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:af4ab5ef652b71f295d02d69f19e8dca81ef1929c6b6c5b85f66b53da62811fb
|
||||
size 43427
|
||||
oid sha256:aa58a3f5fa6ee6e9a7f89f87a64b7b43577fca75cd44193b521875c8d6a184e3
|
||||
size 43823
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f28ac645ba2e330a8cdbdc8e26040a1f3c02e0e647975bfbed5e7dc175bd372b
|
||||
size 43769
|
||||
oid sha256:50cbc5955836725e0f58f2058e2c43cce0639c122036470fac58b89f3208c7f2
|
||||
size 44139
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0e32044f02911fa178f7030eab11ccd04bd02f82811eb86aeb585d5116e76d75
|
||||
size 37682
|
||||
oid sha256:e6787391e332dcf4dd0998c18447962a1ee03314e276f6b7d0a6bd6717f30f43
|
||||
size 38214
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:079c29fb8bc0bc1d8c8899a0ec13d997127d57d5d49ad04906247038f8b39d2f
|
||||
size 39196
|
||||
oid sha256:acaa3c96e40cd2d2d0cace906e87a6e36801a0836b1eff059a2f0a031e41ddd8
|
||||
size 38770
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b5623e3f37e2aa89cdce2a8d1181c8f417fa05917bf62fc46b541b86d140a780
|
||||
size 44611
|
||||
oid sha256:b0ac4827780ad236721b793b1d07a3f7ee514811ca3d8f29c8d447cdb99e739e
|
||||
size 45293
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ce0bbe6be7ede759386ef4c56afef4f419ee0c6264bc80b22a3a2b563a170807
|
||||
size 45096
|
||||
oid sha256:57f7684c300496d7c8ca31e500b2191b85e3bc2ecbce489e77f1c71edec3d877
|
||||
size 45790
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9ccef4dc0eed428153c228253c198dcfb7ff5c18d6e6a44d31dff6ac548f4f61
|
||||
size 38558
|
||||
oid sha256:fb973d123139c6da77e5b764cbca51866310ea81caf7057c584064677d2deff8
|
||||
size 39233
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b75570c52aeecb3a377dbf54cc53b439b040ddd66f44b18ae358ee61887067bf
|
||||
size 30316
|
||||
oid sha256:245701b0b6fbb5f886af725435ea62ac2ed2164ae51cc74ed3560c49d5692144
|
||||
size 26585
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue