Skip to content

Commit

Permalink
feat: border effect item in zapping mode is on.
Browse files Browse the repository at this point in the history
  • Loading branch information
oxyroid committed Dec 13, 2023
1 parent a987ffb commit 8364fac
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 35 deletions.
12 changes: 8 additions & 4 deletions data/src/main/java/com/m3u/data/database/entity/Live.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,16 @@ data class Live(

@Immutable
data class LiveHolder(
val lives: List<Live>
val lives: List<Live> = emptyList(),
val floating: Live? = null
)

@Composable
fun rememberLiveHolder(lives: List<Live>): LiveHolder {
return remember(lives) {
LiveHolder(lives)
fun rememberLiveHolder(
lives: List<Live>,
floating: Live? = null
): LiveHolder {
return remember(lives, floating) {
LiveHolder(lives, floating)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class AboutViewModel @Inject constructor(
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.Lazily,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = emptyList()
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ fun FavouriteRoute(
val helper = LocalHelper.current
val pref = LocalPref.current
val state by viewModel.state.collectAsStateWithLifecycle()
val floating by viewModel.floating.collectAsStateWithLifecycle()

val lives = remember(state.details) {
state.details.flatMap { it.value }
Expand All @@ -58,7 +59,10 @@ fun FavouriteRoute(
FavoriteScreen(
contentPadding = contentPadding,
rowCount = pref.rowCount,
liveHolder = rememberLiveHolder(lives),
liveHolder = rememberLiveHolder(
lives = lives,
floating = floating
),
navigateToLive = navigateToLive,
modifier = modifier
.fillMaxSize()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
package com.m3u.features.favorite

import android.util.Log
import androidx.lifecycle.viewModelScope
import com.m3u.core.architecture.pref.Pref
import com.m3u.core.architecture.pref.observeAsFlow
import com.m3u.core.architecture.viewmodel.BaseViewModel
import com.m3u.core.util.collections.filterNotNullKeys
import com.m3u.core.wrapper.EmptyMessage
import com.m3u.data.repository.FeedRepository
import com.m3u.data.repository.LiveRepository
import com.m3u.data.service.PlayerManager
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import javax.inject.Inject

@HiltViewModel
class FavouriteViewModel @Inject constructor(
liveRepository: LiveRepository,
feedRepository: FeedRepository
feedRepository: FeedRepository,
pref: Pref,
playerManager: PlayerManager
) : BaseViewModel<FavoriteState, FavoriteEvent, EmptyMessage>(
emptyState = FavoriteState()
) {
Expand All @@ -39,6 +48,29 @@ class FavouriteViewModel @Inject constructor(
.launchIn(viewModelScope)
}

private val zappingMode = pref
.observeAsFlow { it.zappingMode }
.onEach { Log.e("FAV", "$it") }
.stateIn(
scope = viewModelScope,
initialValue = Pref.DEFAULT_ZAPPING_MODE,
started = SharingStarted.WhileSubscribed(5_000)
)

val floating = combine(
zappingMode,
playerManager.url,
liveRepository.observeAll()
) { zappingMode, url, lives ->
if (!zappingMode) null
else lives.find { it.url == url }
}
.stateIn(
scope = viewModelScope,
initialValue = null,
started = SharingStarted.WhileSubscribed(5_000)
)

override fun onEvent(event: FavoriteEvent) {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ internal fun FavouriteGallery(
val pref = LocalPref.current
val helper = LocalHelper.current
val lives = liveHolder.lives
val floating = liveHolder.floating
LazyVerticalStaggeredGrid(
columns = StaggeredGridCells.Fixed(rowCount),
verticalItemSpacing = spacing.medium,
Expand All @@ -44,6 +45,7 @@ internal fun FavouriteGallery(
FavoriteItem(
live = live,
noPictureMode = pref.noPictureMode,
border = floating != live,
onClick = {
helper.play(live.url)
navigateToLive()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Text
Expand All @@ -32,14 +33,17 @@ internal fun FavoriteItem(
noPictureMode: Boolean,
onClick: () -> Unit,
onLongClick: () -> Unit,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
border: Boolean = true,
) {
val context = LocalContext.current
val spacing = LocalSpacing.current

val scheme = remember(live.url) { URI(live.url).scheme ?: context.getString(string.feat_feed_scheme_unknown) }

OutlinedCard {
OutlinedCard(
border = CardDefaults.outlinedCardBorder(border)
) {
Column(
modifier = Modifier
.combinedClickable(
Expand Down
25 changes: 19 additions & 6 deletions features/feed/src/main/java/com/m3u/features/feed/FeedScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ internal fun FeedRoute(

val state by viewModel.state.collectAsStateWithLifecycle()
val message by viewModel.message.collectAsStateWithLifecycle()
val floating by viewModel.floating.collectAsStateWithLifecycle()
var dialogStatus: DialogStatus by remember { mutableStateOf(DialogStatus.Idle) }
val writeExternalPermissionState = rememberPermissionState(
Manifest.permission.WRITE_EXTERNAL_STORAGE
Expand Down Expand Up @@ -164,7 +165,10 @@ internal fun FeedRoute(
query = state.query,
onQuery = { viewModel.onEvent(FeedEvent.Query(it)) },
rowCount = pref.rowCount,
channelHolder = rememberChannelHolder(state.channels),
channelHolder = rememberChannelHolder(
channels = state.channels,
floating = floating
),
scrollUp = state.scrollUp,
refreshing = state.fetching,
onRefresh = { viewModel.onEvent(FeedEvent.Refresh) },
Expand Down Expand Up @@ -261,7 +265,9 @@ private fun FeedScreen(
text = query,
onValueChange = onQuery,
fontWeight = FontWeight.Bold,
placeholder = stringResource(string.feat_feed_query_placeholder).capitalize(Locale.current)
placeholder = stringResource(string.feat_feed_query_placeholder).capitalize(
Locale.current
)
)
}
},
Expand Down Expand Up @@ -300,8 +306,9 @@ private fun FeedScreen(
EventHandler(scrollUp) {
state.animateScrollToItem(0)
}
val actualRowCount = remember(configuration.orientation, rowCount) {
when (configuration.orientation) {
val orientation = configuration.orientation
val actualRowCount = remember(orientation, rowCount) {
when (orientation) {
ORIENTATION_LANDSCAPE -> rowCount + 2
ORIENTATION_PORTRAIT -> rowCount
else -> rowCount
Expand Down Expand Up @@ -379,6 +386,7 @@ private fun FeedPager(
val theme = MaterialTheme.colorScheme
Column(modifier) {
val channels = channelHolder.channels
val floating = channelHolder.floating
val pagerState = rememberPagerState { channels.size }
val coroutineScope = rememberCoroutineScope()
if (channels.size > 1) {
Expand Down Expand Up @@ -418,11 +426,16 @@ private fun FeedPager(
modifier = Modifier.fillMaxWidth()
)
}
val holders = List(channels.size) { rememberLiveHolder(channels[it].lives) }
val holders = List(channels.size) {
rememberLiveHolder(
lives = channels[it].lives,
floating = floating
)
}
HorizontalPager(
state = pagerState
) { pager ->
content(holders[pager])
content(holders[pager].copy(floating = floating))
}
}
}
13 changes: 9 additions & 4 deletions features/feed/src/main/java/com/m3u/features/feed/FeedState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,24 @@ data class Channel(

@Immutable
data class ChannelHolder(
val channels: List<Channel>
val channels: List<Channel>,
val floating: Live? = null
)

@Composable
fun rememberChannelHolder(channels: List<Channel>): ChannelHolder {
return remember(channels) {
ChannelHolder(channels)
fun rememberChannelHolder(
channels: List<Channel>,
floating: Live? = null
): ChannelHolder {
return remember(channels, floating) {
ChannelHolder(channels, floating)
}
}

data class FeedState(
val url: String = "",
val channels: List<Channel> = emptyList(),
val floating: Live? = null,
val query: String = "",
val fetching: Boolean = false,
val scrollUp: Event<Unit> = handledEvent(),
Expand Down
27 changes: 27 additions & 0 deletions features/feed/src/main/java/com/m3u/features/feed/FeedViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.m3u.features.feed
import androidx.lifecycle.viewModelScope
import com.m3u.core.architecture.Logger
import com.m3u.core.architecture.pref.Pref
import com.m3u.core.architecture.pref.observeAsFlow
import com.m3u.core.architecture.viewmodel.BaseViewModel
import com.m3u.core.architecture.viewmodel.catch
import com.m3u.core.architecture.viewmodel.map
Expand All @@ -15,14 +16,17 @@ import com.m3u.data.repository.LiveRepository
import com.m3u.data.repository.MediaRepository
import com.m3u.data.repository.observeAll
import com.m3u.data.repository.refresh
import com.m3u.data.service.PlayerManager
import com.m3u.features.feed.FeedMessage.LiveCoverSaved
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject
Expand All @@ -32,6 +36,7 @@ class FeedViewModel @Inject constructor(
private val liveRepository: LiveRepository,
private val feedRepository: FeedRepository,
private val mediaRepository: MediaRepository,
private val playerManager: PlayerManager,
private val pref: Pref,
@Logger.Ui private val logger: Logger
) : BaseViewModel<FeedState, FeedEvent, FeedMessage>(
Expand All @@ -49,6 +54,28 @@ class FeedViewModel @Inject constructor(
}
}

private val zappingMode = pref
.observeAsFlow { it.zappingMode }
.stateIn(
scope = viewModelScope,
initialValue = Pref.DEFAULT_ZAPPING_MODE,
started = SharingStarted.WhileSubscribed(5_000)
)

val floating = combine(
zappingMode,
playerManager.url,
liveRepository.observeAll()
) { zappingMode, url, lives ->
if (!zappingMode) null
else lives.find { it.url == url }
}
.stateIn(
scope = viewModelScope,
initialValue = null,
started = SharingStarted.WhileSubscribed(5_000)
)

private var observeJob: Job? = null
private fun observe(feedUrl: String) {
observeJob?.cancel()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ internal fun LiveGallery(
val pref = LocalPref.current

val lives = liveHolder.lives
val floating = liveHolder.floating

LazyVerticalGrid(
state = state,
Expand All @@ -53,6 +54,7 @@ internal fun LiveGallery(
) { live ->
LiveItem(
live = live,
border = floating != live,
noPictureMode = pref.noPictureMode,
onClick = {
play(live.url)
Expand All @@ -77,6 +79,7 @@ internal fun TvFeedGallery(
val spacing = LocalSpacing.current
val pref = LocalPref.current
val lives = liveHolder.lives
val floating = liveHolder.floating

TvLazyVerticalGrid(
state = state,
Expand All @@ -93,6 +96,7 @@ internal fun TvFeedGallery(
) { live ->
LiveItem(
live = live,
border = floating != live,
noPictureMode = pref.noPictureMode,
onClick = {
play(live.url)
Expand Down
Loading

0 comments on commit 8364fac

Please sign in to comment.