File: new design for file timeline item
This commit is contained in:
@@ -18,12 +18,13 @@ package io.element.android.features.messages.impl.timeline.components.event
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Attachment
|
||||
import androidx.compose.material.icons.filled.AttachFile
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -33,6 +34,7 @@ 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.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContentProvider
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
@@ -47,7 +49,6 @@ fun TimelineItemFileView(
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
@@ -57,16 +58,23 @@ fun TimelineItemFileView(
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Attachment,
|
||||
modifier = Modifier.size(20.dp),
|
||||
imageVector = Icons.Filled.AttachFile,
|
||||
contentDescription = "OpenFile"
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = content.body,
|
||||
modifier = Modifier.padding(horizontal = 8.dp),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Column(modifier = Modifier.padding(horizontal = 8.dp),) {
|
||||
Text(
|
||||
text = content.name,
|
||||
maxLines = 2,
|
||||
fontSize = 16.sp,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = content.fileExtensionAndSize,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent
|
||||
import io.element.android.features.messages.impl.timeline.util.FileSizeFormatter
|
||||
import io.element.android.features.messages.impl.timeline.util.toHtmlDocument
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType
|
||||
@@ -34,7 +35,9 @@ import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageTy
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentMessageFactory @Inject constructor() {
|
||||
class TimelineItemContentMessageFactory @Inject constructor(
|
||||
private val fileSizeFormatter: FileSizeFormatter
|
||||
) {
|
||||
|
||||
fun create(content: MessageContent): TimelineItemEventContent {
|
||||
return when (val messageType = content.type) {
|
||||
@@ -70,11 +73,13 @@ class TimelineItemContentMessageFactory @Inject constructor() {
|
||||
)
|
||||
}
|
||||
is FileMessageType -> TimelineItemFileContent(
|
||||
body = messageType.body,
|
||||
name = messageType.body,
|
||||
thumbnailSource = messageType.info?.thumbnailSource,
|
||||
fileSource = messageType.source,
|
||||
mimeType = messageType.info?.mimetype,
|
||||
size = messageType.info?.size,
|
||||
formattedFileSize = messageType.info?.size?.let {
|
||||
fileSizeFormatter.format(it)
|
||||
},
|
||||
)
|
||||
is NoticeMessageType -> TimelineItemNoticeContent(
|
||||
body = messageType.body,
|
||||
|
||||
@@ -19,11 +19,20 @@ package io.element.android.features.messages.impl.timeline.model.event
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
|
||||
data class TimelineItemFileContent(
|
||||
val body: String,
|
||||
val name: String,
|
||||
val fileSource: MediaSource,
|
||||
val thumbnailSource: MediaSource?,
|
||||
val size: Long?,
|
||||
val formattedFileSize: String?,
|
||||
val mimeType: String?,
|
||||
) : TimelineItemEventContent {
|
||||
override val type: String = "TimelineItemFileContent"
|
||||
|
||||
private val fileExtension = name.substringAfterLast('.', "").uppercase()
|
||||
val fileExtensionAndSize = buildString {
|
||||
append(fileExtension)
|
||||
if (formattedFileSize != null) {
|
||||
append(' ')
|
||||
append("($formattedFileSize)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,14 +25,14 @@ open class TimelineItemFileContentProvider : PreviewParameterProvider<TimelineIt
|
||||
get() = sequenceOf(
|
||||
aTimelineItemFileContent("A file.pdf"),
|
||||
aTimelineItemFileContent("A bigger name file.pdf"),
|
||||
aTimelineItemFileContent("An even bigger file name which doesn't fit.pdf"),
|
||||
aTimelineItemFileContent("An even bigger bigger bigger bigger bigger bigger bigger file name which doesn't fit .pdf"),
|
||||
)
|
||||
}
|
||||
|
||||
fun aTimelineItemFileContent(fileName: String) = TimelineItemFileContent(
|
||||
body = fileName,
|
||||
name = fileName,
|
||||
thumbnailSource = MediaSource(url = ""),
|
||||
fileSource = MediaSource(url = ""),
|
||||
mimeType = MimeTypes.OctetStream,
|
||||
size = 100
|
||||
formattedFileSize = "100kB"
|
||||
)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.messages.impl.timeline.util
|
||||
|
||||
import android.content.Context
|
||||
import android.text.format.Formatter
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import javax.inject.Inject
|
||||
|
||||
interface FileSizeFormatter {
|
||||
/**
|
||||
* Formats a content size to be in the form of bytes, kilobytes, megabytes, etc.
|
||||
*/
|
||||
fun format(fileSize: Long): String
|
||||
}
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class AndroidFileSizeFormatter @Inject constructor(@ApplicationContext private val context: Context) : FileSizeFormatter {
|
||||
override fun format(fileSize: Long): String {
|
||||
return Formatter.formatShortFileSize(context, fileSize)
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import io.element.android.features.messages.impl.timeline.factories.event.Timeli
|
||||
import io.element.android.features.messages.impl.timeline.factories.virtual.TimelineItemDaySeparatorFactory
|
||||
import io.element.android.features.messages.impl.timeline.factories.virtual.TimelineItemVirtualFactory
|
||||
import io.element.android.features.messages.impl.timeline.groups.TimelineItemGrouper
|
||||
import io.element.android.features.messages.timeline.FakeFileSizeFormatter
|
||||
import io.element.android.libraries.dateformatter.test.FakeDaySeparatorFormatter
|
||||
import io.element.android.libraries.eventformatter.api.TimelineEventFormatter
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
|
||||
@@ -42,7 +43,7 @@ internal fun aTimelineItemsFactory(): TimelineItemsFactory {
|
||||
dispatchers = testCoroutineDispatchers(),
|
||||
eventItemFactory = TimelineItemEventFactory(
|
||||
TimelineItemContentFactory(
|
||||
messageFactory = TimelineItemContentMessageFactory(),
|
||||
messageFactory = TimelineItemContentMessageFactory(FakeFileSizeFormatter()),
|
||||
redactedMessageFactory = TimelineItemContentRedactedFactory(),
|
||||
stickerFactory = TimelineItemContentStickerFactory(),
|
||||
utdFactory = TimelineItemContentUTDFactory(),
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.messages.timeline
|
||||
|
||||
import io.element.android.features.messages.impl.timeline.util.FileSizeFormatter
|
||||
|
||||
class FakeFileSizeFormatter : FileSizeFormatter {
|
||||
override fun format(fileSize: Long): String {
|
||||
return "$fileSize Bytes"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user