SDP-GeoHunt/geo-hunt

View on GitHub
app/src/main/java/com/github/geohunt/app/ui/screens/home/ChallengeFeed.kt

Summary

Maintainability
D
1 day
Test Coverage
F
0%
package com.github.geohunt.app.ui.screens.home

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import com.github.geohunt.app.R
import com.github.geohunt.app.model.Challenge
import com.github.geohunt.app.model.User
import com.github.geohunt.app.ui.components.appbar.HomeScreenFeed
import com.github.geohunt.app.ui.components.cards.ChallengeCard

@Composable
fun ChallengeFeed(
    chosenFeed: HomeScreenFeed,
    onUserClick: (User) -> Unit,
    onOpenMap: (Challenge) -> Unit,
    onOpenChallenge: (Challenge) -> Unit,
    onClaim: (Challenge) -> Unit,
    onOpenExplore: () -> Unit,
    viewModel: HomeFeedViewModel = viewModel(factory = HomeFeedViewModel.Factory)
) {
    val feed = viewModel.getFeed(chosenFeed)
    val challenges = feed.challenges.collectAsStateWithLifecycle()

    when {
        challenges.value == null -> Box(modifier = Modifier.fillMaxSize()) {
            CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
        }

        challenges.value!!.isEmpty() -> Column(modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
            verticalArrangement = Arrangement.Center
        ) {
            Text(
                stringResource(R.string.empty_feed_title),
                style = MaterialTheme.typography.titleMedium
            )

            Text(
                stringResource(R.string.empty_feed_subtitle),
                style = MaterialTheme.typography.labelMedium
            )

            Spacer(Modifier.height(12.dp))

            Button(onClick = onOpenExplore, modifier = Modifier.align(Alignment.CenterHorizontally)) {
                Text(stringResource(R.string.open_the_map))
            }
        }

        else -> LazyColumn(
            Modifier.padding(horizontal = 16.dp),
            verticalArrangement = Arrangement.spacedBy(12.dp)
        ) {
            // Additional null check to avoid NPE
            if (challenges.value != null) {
                items(
                    challenges.value!!,
                    key = { it.id }
                ) { challenge ->
                    val huntState = feed.getChallengeHuntState(challenge).collectAsStateWithLifecycle()
                    val author = feed.getAuthor(challenge).collectAsStateWithLifecycle()
                    val isFollowing = viewModel.isFollowing(author.value).collectAsStateWithLifecycle(initialValue = false)
                    val isBusy = feed.isBusy(challenge).collectAsStateWithLifecycle()

                    ChallengeCard(
                        challenge = challenge,
                        huntState = huntState.value,
                        author = author.value,
                        onUserClick = onUserClick,
                        userLocation = { viewModel.userLocation.value },
                        onImageClick = { onOpenChallenge(challenge) },
                        onOpenMap = { onOpenMap(challenge) },
                        isFollowing = isFollowing.value,
                        onFollow = { user, follow -> if (follow) viewModel.follow(user) else viewModel.unfollow(user) },
                        onHunt = { feed.hunt(challenge) } ,
                        onLeaveHunt = { feed.leaveHunt(challenge) },
                        onClaim = { onClaim(challenge) },
                        isBusy = { isBusy.value }
                    )
                }

                // Whitespace
                item {
                    Spacer(Modifier.height(12.dp))
                }
            }
        }
    }
}