simple photo viewer

This commit is contained in:
2024-07-16 10:29:37 +03:00
parent 9e09cbb640
commit 1817698031
27 changed files with 484 additions and 278 deletions
@@ -16,6 +16,7 @@ object Conversations
fun NavGraphBuilder.conversationsScreen(
onError: (BaseError) -> Unit,
onConversationItemClicked: (id: Int) -> Unit,
onPhotoClicked: (url: String) -> Unit,
navController: NavController,
) {
composable<Conversations> {
@@ -25,6 +26,7 @@ fun NavGraphBuilder.conversationsScreen(
ConversationsRoute(
onError = onError,
onConversationItemClicked = onConversationItemClicked,
onPhotoClicked = onPhotoClicked,
viewModel = viewModel
)
}
@@ -1,6 +1,5 @@
package dev.meloda.fast.conversations.presentation
import android.graphics.drawable.ColorDrawable
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.fadeIn
@@ -8,6 +7,7 @@ import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
@@ -41,47 +41,27 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import dev.meloda.fast.common.model.UiImage
import dev.meloda.fast.conversations.model.ConversationOption
import dev.meloda.fast.conversations.model.UiConversation
import dev.meloda.fast.ui.basic.ContentAlpha
import dev.meloda.fast.ui.basic.LocalContentAlpha
import dev.meloda.fast.ui.components.DotsFlashing
import dev.meloda.fast.ui.util.getImage
import dev.meloda.fast.ui.util.getResourcePainter
import dev.meloda.fast.ui.util.getString
import dev.meloda.fast.ui.R as UiR
val BirthdayColor = Color(0xffb00b69)
@Composable
fun UiImage.getResourcePainter(): Painter? {
return when (this) {
is UiImage.Resource -> painterResource(id = resId)
else -> null
}
}
@Composable
fun UiImage.getImage(): Any {
return when (this) {
is UiImage.Color -> ColorDrawable(color)
is UiImage.ColorResource -> ColorDrawable(colorResource(id = resId).toArgb())
is UiImage.Resource -> painterResource(id = resId)
is UiImage.Simple -> drawable
is UiImage.Url -> url
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ConversationItem(
@@ -92,6 +72,7 @@ fun ConversationItem(
isUserAccount: Boolean,
conversation: UiConversation,
modifier: Modifier = Modifier,
onPhotoClicked: (url: String) -> Unit
) {
val context = LocalContext.current
val hapticFeedback = LocalHapticFeedback.current
@@ -174,7 +155,12 @@ fun ConversationItem(
contentDescription = "Avatar",
modifier = Modifier
.fillMaxSize()
.clip(CircleShape),
.clip(CircleShape)
.clickable {
if (avatarImage is String) {
onPhotoClicked(avatarImage)
}
},
placeholder = painterResource(id = UiR.drawable.ic_account_circle_cut)
)
}
@@ -32,7 +32,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Composable
fun ConversationsListComposable(
fun ConversationsList(
onConversationsClick: (Int) -> Unit,
onConversationsLongClick: (UiConversation) -> Unit,
screenState: ConversationsScreenState,
@@ -40,7 +40,8 @@ fun ConversationsListComposable(
maxLines: Int,
modifier: Modifier,
onOptionClicked: (UiConversation, ConversationOption) -> Unit,
padding: PaddingValues
padding: PaddingValues,
onPhotoClicked: (url: String) -> Unit
) {
val coroutineScope = rememberCoroutineScope()
@@ -72,7 +73,8 @@ fun ConversationsListComposable(
maxLines = maxLines,
isUserAccount = isUserAccount,
conversation = conversation,
modifier = Modifier.animateItem(fadeInSpec = null, fadeOutSpec = null)
modifier = Modifier.animateItem(fadeInSpec = null, fadeOutSpec = null),
onPhotoClicked = onPhotoClicked
)
Spacer(modifier = Modifier.height(8.dp))
@@ -66,6 +66,10 @@ import androidx.core.view.HapticFeedbackConstantsCompat
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil.imageLoader
import coil.request.ImageRequest
import dev.chrisbanes.haze.haze
import dev.chrisbanes.haze.hazeChild
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
import dev.chrisbanes.haze.materials.HazeMaterials
import dev.meloda.fast.conversations.ConversationsViewModel
import dev.meloda.fast.conversations.ConversationsViewModelImpl
import dev.meloda.fast.conversations.model.ConversationOption
@@ -80,10 +84,6 @@ import dev.meloda.fast.ui.theme.LocalBottomPadding
import dev.meloda.fast.ui.theme.LocalHazeState
import dev.meloda.fast.ui.theme.LocalThemeConfig
import dev.meloda.fast.ui.util.isScrollingUp
import dev.chrisbanes.haze.haze
import dev.chrisbanes.haze.hazeChild
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
import dev.chrisbanes.haze.materials.HazeMaterials
import kotlinx.coroutines.launch
import org.koin.androidx.compose.koinViewModel
import org.koin.compose.koinInject
@@ -93,6 +93,7 @@ import dev.meloda.fast.ui.R as UiR
fun ConversationsRoute(
onError: (BaseError) -> Unit,
onConversationItemClicked: (conversationId: Int) -> Unit,
onPhotoClicked: (url: String) -> Unit,
viewModel: ConversationsViewModel = koinViewModel<ConversationsViewModelImpl>()
) {
val context = LocalContext.current
@@ -130,7 +131,8 @@ fun ConversationsRoute(
onOptionClicked = viewModel::onOptionClicked,
onPaginationConditionsMet = viewModel::onPaginationConditionsMet,
onRefreshDropdownItemClicked = viewModel::onRefresh,
onRefresh = viewModel::onRefresh
onRefresh = viewModel::onRefresh,
onPhotoClicked = onPhotoClicked
)
@@ -156,7 +158,8 @@ fun ConversationsScreen(
onOptionClicked: (UiConversation, ConversationOption) -> Unit = { _, _ -> },
onPaginationConditionsMet: () -> Unit = {},
onRefreshDropdownItemClicked: () -> Unit = {},
onRefresh: () -> Unit = {}
onRefresh: () -> Unit = {},
onPhotoClicked: (url: String) -> Unit = {}
) {
val view = LocalView.current
val currentTheme = LocalThemeConfig.current
@@ -349,7 +352,7 @@ fun ConversationsScreen(
} else Modifier
)
) {
ConversationsListComposable(
ConversationsList(
onConversationsClick = onConversationItemClicked,
onConversationsLongClick = onConversationItemLongClicked,
screenState = screenState,
@@ -364,7 +367,8 @@ fun ConversationsScreen(
Modifier
}.fillMaxSize(),
onOptionClicked = onOptionClicked,
padding = padding
padding = padding,
onPhotoClicked = onPhotoClicked
)
if (enablePullToRefresh) {