-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add feature navigate between channels in Player #207
base: master
Are you sure you want to change the base?
Add feature navigate between channels in Player #207
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert some unnecessary formatting changes. Including Linebreak and contraction.
4ca54ae
to
dbb72f9
Compare
feature/channel/src/main/java/com/m3u/feature/channel/ChannelMask.kt
Outdated
Show resolved
Hide resolved
feature/channel/src/main/java/com/m3u/feature/channel/ChannelViewModel.kt
Show resolved
Hide resolved
feature/channel/src/main/java/com/m3u/feature/channel/ChannelViewModel.kt
Show resolved
Hide resolved
feature/channel/src/main/java/com/m3u/feature/channel/ChannelScreen.kt
Outdated
Show resolved
Hide resolved
I have a new idea to find out the adjacent channels: Define a new class to hold the SQL result.// Channel.kt
data class AdjacentChannels(
@ColumnInfo("prev")
val prev: Channel?,
@ColumnInfo("next")
val next: Channel?
) Add a method which returns "Flow"// ChannelDao.kt
/**
* Observe the two channels adjacent to a specific channel in a particular channel order.
* If the channel is not in this channel order, a null object will be returned.
*/
@Query(
"""
Write SQL here.
"""
)
fun observeAdjacentChannels(
channelId: Int,
playlistUrl: String,
category: String
): Flow<AdjacentChannels?>
|
Then, because it is not a collection, you can maintain it directly in the viewmodel through a series of operators such as combine/map/stateIn like other flows without performance problems. // ChannelViewModel.kt
val adjacentChannels: StateFlow<AdjacentChannels?> = flatmapCombined(playlist, channel) { playlist, channel ->
playlist?: return@flatmapCombined flowOf(null)
channel?: return@flatmapCombined flowOf(null)
// Don't forget to define the same method in repository because viewModel shouldn't hold the DAO instance.
channelRepository.observeAdjacentChannels(
channelId = channel.id,
playlistUrl = playlist.url,
category = channel.category
)
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.Lazily,
initialValue = null
) In addition, you need to modify the function flatmapCombined in the project, it has some problems. fun <R> flatmapCombined(
flows: Iterable<Flow<Any?>>,
transform: (keys: Array<Any?>) -> Flow<R>
): Flow<R> = combine(flows) { it }.flatMapLatest { keys -> transform(keys) }
@Suppress("UNCHECKED_CAST")
fun <T1, T2, R> flatmapCombined(
flow1: Flow<T1>,
flow2: Flow<T2>,
transform: (t1: T1, t2: T2) -> Flow<R>
): Flow<R> = flatmapCombined(listOf(flow1, flow2)) { keys ->
transform(keys[0] as T1, keys[1] as T2)
}
@Suppress("UNCHECKED_CAST")
fun <T1, T2, T3, R> flatmapCombined(
flow1: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>,
transform: (t1: T1, t2: T2, t3: T3) -> Flow<R>
): Flow<R> = flatmapCombined(listOf(flow1, flow2, flow3)) { keys ->
transform(keys[0] as T1, keys[1] as T2, keys[2] as T3)
}
@Suppress("UNCHECKED_CAST")
fun <T1, T2, T3, T4, R> flatmapCombined(
flow1: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>,
flow4: Flow<T4>,
transform: (t1: T1, t2: T2, t3: T3, t4: T4) -> Flow<R>
): Flow<R> = flatmapCombined(listOf(flow1, flow2, flow3, flow4)) { keys ->
transform(keys[0] as T1, keys[1] as T2, keys[2] as T3, keys[3] as T4)
} Then, you can call collectAsState to convert it in the UI layer. val adjacentChannels = viewModel.adjacentChannels.collectAsStateWithLifecycle() This way has a great advantage, that is, you can control in real time whether the previous or next button is enabled or not. MaskButton(
enabled = adjacentChannels != null && adjacentChannels.prev != null,
onClick = {
val prev = adjacentChannels.prev
if (adjacentChannels != null && prev != null) {
helper.play(MediaCommand.Common(prev.id))
}
}
) |
* feat: overscroll effect. * fix: remove unused import directive.
* feat: overscroll effect. * fix: remove unused import directive. * fix: overscroll effect. * fix: remove unused import directive.
…/github.com/tungnk123/M3UAndroid into feature/issue-201-navigate-between-channels
Could you pls review this pull request? |
No description provided.