how to update the link where the video player plays the video

33 Views Asked by At

I can’t understand why the view is not updated

@Composable
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
fun VideoPlayer(
screenHeight: Dp, screenWidth: Dp, attachment: MediaAttachment, feedViewModel: FeedViewModel
) {
val context = LocalContext.current
val currentSource by feedViewModel.currentSource.observeAsState(attachment.Video)

    Toast.makeText(context, currentSource.toString(), Toast.LENGTH_SHORT).show()
    
    var exoPlayer = remember(currentSource) {
        ExoPlayer.Builder(context).build().apply {
                val defaultDataSourceFactory = DefaultDataSource.Factory(context)
                val dataSourceFactory: DataSource.Factory = DefaultDataSource.Factory(
                    context, defaultDataSourceFactory
                )
                val source = ProgressiveMediaSource.Factory(dataSourceFactory)
                    .createMediaSource(MediaItem.fromUri("https://senses.team/$currentSource"))
    
                setMediaSource(source)
                prepare()
            }
    }
    
    exoPlayer.playWhenReady = true
    exoPlayer.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
    exoPlayer.repeatMode = Player.REPEAT_MODE_ONE
    
    DisposableEffect(
        AndroidView(modifier = Modifier
            .height(screenHeight)
            .width(screenWidth)
            .background(Color.Black),
            factory = {
                CustomExoPlayerView(context).apply {
                    hideController()
                    useController = false
                    resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
                    player = exoPlayer
                    layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
                }
            })
    ) {
        onDispose { exoPlayer.release() }
    }

}

@UnstableApi
internal class CustomExoPlayerView(
context: Context, attributeSet: AttributeSet? = null,
) : PlayerView(context, attributeSet) {

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -\> {
                showController()
            }
        }
        return false
    }

}

my ViewModel for storage current video source

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.android.senses.structs.Sense
import com.android.senses.ui.navigation.screens.home.ListOfSenses

class FeedViewModel : ViewModel() {

    private val _listOfSenses = MutableLiveData<List<Sense>>(ListOfSenses)
    val listOfSenses: MutableLiveData<List<Sense>> = _listOfSenses

    private val _currentSource = MutableLiveData<String>()
    val currentSource: LiveData<String> = _currentSource

    fun setCurrentSource(source: String) {
        _currentSource.value = source
    }
}

and there is a lazy list that, when clicked, changes the link in the viewmodel

package com.android.senses.ui.navigation.screens.home

import FeedViewModel
import android.annotation.SuppressLint
import android.content.Context
import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.navigation.NavController
import com.android.senses.R
import com.android.senses.structs.Sense
import com.android.senses.ui.LoadImageWithGlide
import com.android.senses.ui.PreloadImageWithGlide
import com.android.senses.ui.VideoPlayer


@SuppressLint(
    "UnusedMaterial3ScaffoldPaddingParameter", "CoroutineCreationDuringComposition",
    "UnrememberedMutableState"
)

@Composable
fun HomeScreen(
    navController: NavController,
    navControllerMain: NavController
) {
    val screenHeight = LocalConfiguration.current.screenHeightDp.dp
    val screenWidth = LocalConfiguration.current.screenWidthDp.dp

    val feedViewModel = FeedViewModel()
    val listOfSenses by feedViewModel.listOfSenses.observeAsState(emptyList())

    var currentSense by remember { mutableStateOf(listOfSenses.get(0)) }
    var currentAttachmentIndex by remember { mutableStateOf(0) }

    val scrollState = rememberLazyListState()

    LazyColumn(
        state = scrollState,
        modifier = Modifier
            .fillMaxSize()
    ) {
        itemsIndexed(items = listOfSenses, key = { _, currentSense -> currentSense.ID })
        { index, sense ->
            PostCard(
                context = LocalContext.current,
                screenHeight = screenHeight,
                screenWidth = screenWidth,
                viewModel = feedViewModel,
                sense = sense,
                feedViewModel= feedViewModel
            )
        }
    }
}
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)

@Composable
fun  PostCard(
    context: Context,
    screenHeight: Dp,
    screenWidth: Dp,
    viewModel: FeedViewModel,
    sense: Sense,
    feedViewModel: FeedViewModel

) {

    var currentAttachmentIndex by remember { mutableStateOf(0) }

    val gradientColors = listOf(
        Color(0xFF000000),
        Color.Transparent,
    )

    val gradientBrush = Brush.verticalGradient(gradientColors)
    val reverseGradientBrush = Brush.verticalGradient(gradientColors.reversed())


    ConstraintLayout(
        modifier = Modifier.fillMaxSize()
    ) {
        val (
            containerGradient1,
            containerGradient2,
            commentContainer,
            reactionContainer
        ) = createRefs()
        Box(
            modifier = Modifier
                .fillMaxSize()
                .clickable {
                    currentAttachmentIndex = (currentAttachmentIndex + 1) % sense.Attachments.size
                    feedViewModel.setCurrentSource(sense.Attachments.get(currentAttachmentIndex).Video)
                    Toast
                        .makeText(context, currentAttachmentIndex.toString(), Toast.LENGTH_SHORT)
                        .show()
                }

        ) {
            if (sense.Attachments.get(currentAttachmentIndex)?.Type != 1) {
                LoadImageWithGlide(
                    imageUrl = sense.Attachments.get(currentAttachmentIndex).Photo,
                    screenHeight = screenHeight,
                    screenWidth = screenWidth,
                    viewModel = viewModel
                )
                VideoPlayer(
                    screenHeight = screenHeight,
                    screenWidth = screenWidth,
                    attachment = sense.Attachments.get(currentAttachmentIndex),
                    feedViewModel= feedViewModel
                )

            } else {
                LoadImageWithGlide(
                    imageUrl = sense.Attachments.get(currentAttachmentIndex).Photo,
                    screenHeight = screenHeight,
                    screenWidth = screenWidth,
                    viewModel = viewModel
                )
            }
            sense.Attachments.forEach {
                PreloadImageWithGlide(imageUrl = it.Photo, context = LocalContext.current)
            }
        }

        //gradient top section
        Column(
            modifier = Modifier
                .constrainAs(containerGradient1) {
                    top.linkTo(parent.top)
                }
                .height(200.dp)
                .fillMaxWidth()
                .background(brush = gradientBrush)
                .alpha(0.2f)

        ) {}

//      head section (title, create sense, messanger and profile image)
        Column(
            modifier = Modifier.fillMaxSize(),

            ) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .fillMaxHeight(0.08f)
                    .padding(start = 10.dp),
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.SpaceAround,
            ) {

                Text(
                    text = LocalContext.current.getString(R.string.home_screen_title),
                    color = Color.White,
                    fontSize = 30.sp,
                    style = MaterialTheme.typography.titleLarge
                )
                Spacer(modifier = Modifier.width(150.dp))
                Row(
                    horizontalArrangement = Arrangement.SpaceBetween
                ) {
                    IconButton(onClick = { /*TODO*/ }) {
                        Icon(
                            painter = painterResource(id = R.drawable.add_icon),
                            contentDescription = "add",
                            tint = Color.White,
                        )
                    }
                    IconButton(
                        onClick = { /*TODO*/ },
                    ) {
                        Icon(
                            painter = painterResource(id = R.drawable.send_message_icon),
                            contentDescription = "send message",
                            tint = Color.White,
                        )
                    }
                }
            }
            Row(
                modifier = Modifier.padding(start = 15.dp, top = 10.dp),
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                Box(

                    modifier = Modifier
                        .size(40.dp)
                        .clip(CircleShape)
                ) {
                    LoadImageWithGlide(
                        sense.Author.avatarUrl,
                        screenHeight,
                        screenWidth,
                        viewModel
                    )
                }
            }
        }

        //reactions section
        Column(
            modifier = Modifier
                .constrainAs(reactionContainer) {
                    bottom.linkTo(commentContainer.top, margin = 70.dp)
                    end.linkTo(parent.end, margin = 10.dp)
                }
                .padding(start = 10.dp)

        ) {
            IconButton(onClick = { /*TODO*/ }) {
                Icon(
                    painter = painterResource(id = R.drawable.comment_icon),
                    contentDescription = "comment",
                    tint = Color.White
                )
            }
            IconButton(onClick = { /*TODO*/ }) {
                Column(
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Icon(
                        painter = painterResource(id = R.drawable.like_icon),
                        contentDescription = "like",
                        tint = if (sense.HasLike) Color.Red else Color.White
                    )
                    Text(
                        text = sense.Likes.toString(),
                        color = Color.White,
                        fontSize = 12.sp,
                    )
                }
            }
        }

        //gradient bottom
        Column(
            modifier = Modifier
                .constrainAs(containerGradient2) {
                    bottom.linkTo(parent.bottom)
                }
                .height(200.dp)
                .fillMaxWidth()
                .background(brush = reverseGradientBrush)
                .alpha(0.2f)

        ) {

        }

        //comment section
        Row(
            modifier = Modifier
                .constrainAs(commentContainer) {
                    bottom.linkTo(parent.bottom)
                }
                .padding(start = 10.dp, end = 10.dp)
                .clickable { }
        ) {
            Column(
                modifier = Modifier
                    .fillMaxWidth(0.9f)
                    .height(150.dp)
                    .clickable { }
            ) {
                Text(
                    text = sense.Text,
                    color = Color.White,
                    fontSize = 15.sp,
                    maxLines = 3
                )
            }
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .size(15.dp)
                    .clickable { }
            ) {
                IconButton(onClick = { /*TODO*/ }) {
                    Icon(
                        painter = painterResource(
                            id = R.drawable.dots_icon
                        ),
                        contentDescription = "more",
                        tint = Color.White,
                    )
                }
            }
        }
    }
}

I tried to use remember state, LaunchedEffect, recreate the player, but the view did not change
I still can’t figure out how to create buttons, for example, for pause and process its clicks, because the player intercepts clicks from the main view

Please help

0

There are 0 best solutions below