Skip to content

Commit

Permalink
Added Shimmer Effect is News Screen
Browse files Browse the repository at this point in the history
  • Loading branch information
aritra-tech committed Aug 18, 2024
1 parent 4f539e9 commit d19f499
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 25 deletions.
63 changes: 38 additions & 25 deletions composeApp/src/commonMain/kotlin/presentation/news/NewsScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import kotlinx.serialization.encodeToString
import navigation.Screens
import org.jetbrains.compose.resources.Font
import org.koin.compose.koinInject
import presentation.home.HomeScreenShimmer
import utils.formatTimeStamp

@Composable
Expand All @@ -60,60 +61,72 @@ fun NewsScreen(
viewModel: NewsViewModel = koinInject()
) {
val navController = LocalNavHost.current
var newsList by remember { mutableStateOf<News?>(null) }
val newsState by viewModel.allNews.collectAsState()
val isLoading by viewModel.isLoading.collectAsState()

LaunchedEffect(Unit) {
viewModel.getAllNews()
}

when(newsState) {
is Resources.ERROR -> {

}
is Resources.LOADING -> {

}

is Resources.SUCCESS -> {
val response = (newsState as Resources.SUCCESS).response
newsList = response
}
}

Scaffold(
topBar = {}
) { paddingValues ->

Column(
modifier = modifier.fillMaxWidth()
modifier = modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.background)
.padding(paddingValues)
.padding(horizontal = 16.dp)
.padding(bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween
) {
newsList?.data?.let { news ->
if (isLoading) {
LazyColumn(
modifier = Modifier.weight(9f).background(MaterialTheme.colorScheme.background),
modifier = Modifier
.weight(9f)
.background(MaterialTheme.colorScheme.background),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(news) { newsData ->
NewsCards(
newsData
) { encodedData ->
Logger.d("Encoded data is: ${encodedData}")
navController.navigate("${Screens.NewsDetails.route}/$encodedData")
items(10) {
NewsScreenShimmer()
}
}
} else {
when (newsState) {
is Resources.SUCCESS -> {
val newsList = (newsState as Resources.SUCCESS<News>).response.data
LazyColumn(
modifier = Modifier
.weight(9f)
.background(MaterialTheme.colorScheme.background),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(newsList) { newsData ->
NewsCards(newsData) { encodedData ->
Logger.d("Encoded data is: $encodedData")
navController.navigate("${Screens.NewsDetails.route}/$encodedData")
}
}
}
}

is Resources.ERROR -> {
Text(
"Error loading data",
color = MaterialTheme.colorScheme.error
)
}

else -> {}
}
}

}
}
}


@Composable
fun NewsCards(
news: Data,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package presentation.news

import androidx.compose.animation.core.*
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
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.unit.dp

@Composable
fun NewsScreenShimmer() {
val shimmerColors = listOf(
Color.LightGray.copy(alpha = 0.6f),
Color.LightGray.copy(alpha = 0.2f),
Color.LightGray.copy(alpha = 0.6f),
)

val transition = rememberInfiniteTransition()
val translateAnim = transition.animateFloat(
initialValue = 0f,
targetValue = 1000f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 1200, easing = FastOutSlowInEasing),
repeatMode = RepeatMode.Restart
)
)

val brush = Brush.linearGradient(
colors = shimmerColors,
start = Offset.Zero,
end = Offset(x = translateAnim.value, y = translateAnim.value)
)

Card(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp),
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceContainer
)
) {
Column(modifier = Modifier.padding(16.dp)) {
Spacer(
modifier = Modifier
.height(200.dp)
.fillMaxWidth()
.clip(RoundedCornerShape(16.dp))
.background(brush)
)

Spacer(modifier = Modifier.height(8.dp))

repeat(3) {
Spacer(
modifier = Modifier
.fillMaxWidth()
.height(10.dp)
.background(brush)
)
Spacer(modifier = Modifier.height(4.dp))
}

Spacer(modifier = Modifier.height(8.dp))

Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Spacer(
modifier = Modifier
.size(24.dp)
.clip(CircleShape)
.background(brush)
)

Spacer(modifier = Modifier.width(8.dp))

Spacer(
modifier = Modifier
.width(80.dp)
.height(10.dp)
.background(brush)
)
}

Spacer(modifier = Modifier.weight(1f))

Spacer(
modifier = Modifier
.width(120.dp)
.height(10.dp)
.background(brush)
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,23 @@ class NewsViewModel(
private val repository: CoinifyRepository
): ViewModel() {

private val _isLoading = MutableStateFlow(true)
val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()

private val _allNews = MutableStateFlow<Resources<News>>(Resources.LOADING)
var allNews: StateFlow<Resources<News>> = _allNews.asStateFlow()

fun getAllNews() {
viewModelScope.launch {
_isLoading.value = true
_allNews.value = Resources.LOADING
try {
val response = repository.getAllNews()
_allNews.value = Resources.SUCCESS(response)
} catch (e: Exception) {
_allNews.value = Resources.ERROR(e.message.toString())
} finally {
_isLoading.value = false
}
}
}
Expand Down

0 comments on commit d19f499

Please sign in to comment.