Skip to content

Commit

Permalink
[feature|optimize|chore] Support select audio tracks, optimize player…
Browse files Browse the repository at this point in the history
… UI code; optimize Feed screen tablet layout; reduce useless permissions
  • Loading branch information
SkyD666 committed May 24, 2024
1 parent dbefa5e commit 3efe7bb
Show file tree
Hide file tree
Showing 32 changed files with 1,339 additions and 839 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ android {
minSdk = 24
targetSdk = 34
versionCode = 16
versionName = "1.1-beta32"
versionName = "1.1-beta33"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down
10 changes: 10 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@
<uses-permission
android:name="android.permission.READ_MEDIA_IMAGES"
tools:ignore="SelectedPhotoAccess" />
<uses-permission
android:name="android.permission.READ_MEDIA_AUDIO"
tools:node="remove" />
<uses-permission
android:name="android.permission.READ_MEDIA_VIDEO"
tools:node="remove" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="29"
tools:node="replace" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import com.skyd.anivu.ui.local.LocalNavController

class Feed1Proxy(
private val visible: (groupId: String) -> Boolean = { true },
private val selected: (FeedBean) -> Boolean = { false },
private val isEnded: (index: Int) -> Boolean = { false },
private val useCardLayout: () -> Boolean = { false },
private val onClick: ((FeedBean) -> Unit)? = null,
Expand All @@ -58,6 +59,7 @@ class Feed1Proxy(
index = index,
data = data,
visible = visible,
selected = selected,
isEnded = isEnded,
useCardLayout = useCardLayout,
onClick = onClick,
Expand All @@ -72,6 +74,7 @@ fun Feed1Item(
index: Int,
data: FeedViewBean,
visible: (groupId: String) -> Boolean,
selected: (FeedBean) -> Boolean,
useCardLayout: () -> Boolean,
onClick: ((FeedBean) -> Unit)? = null,
isEnded: (index: Int) -> Boolean,
Expand All @@ -97,8 +100,12 @@ fun Feed1Item(
} else RectangleShape
)
.run {
if (useCardLayout()) background(color = MaterialTheme.colorScheme.surfaceContainer)
else this
if (useCardLayout()) {
background(
if (selected(feed)) MaterialTheme.colorScheme.surfaceContainerHighest
else MaterialTheme.colorScheme.surfaceContainer
)
} else this
}
.combinedClickable(
onLongClick = if (onRemove != null && onEdit != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import com.skyd.anivu.ui.mpv.ForwardRippleDirect
import com.skyd.anivu.ui.mpv.controller.ForwardRippleDirect

class ForwardRippleShape(private val direct: ForwardRippleDirect) : Shape {
override fun createOutline(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ private fun ArticleList(
}
AniVuLazyVerticalGrid(
modifier = modifier.fillMaxSize(),
columns = GridCells.Adaptive(300.dp),
columns = GridCells.Adaptive(360.dp),
dataList = articles,
adapter = adapter,
contentPadding = contentPadding,
Expand Down
40 changes: 31 additions & 9 deletions app/src/main/java/com/skyd/anivu/ui/fragment/feed/FeedScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.material3.adaptive.currentWindowSize
import androidx.compose.material3.adaptive.layout.AnimatedPane
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
Expand All @@ -61,6 +62,7 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
Expand Down Expand Up @@ -116,11 +118,22 @@ fun FeedScreen() {
)
val navController = LocalNavController.current
val windowSizeClass = LocalWindowSizeClass.current
val density = LocalDensity.current

BackHandler(navigator.canNavigateBack()) {
var listPaneSelectedFeedUrls by remember { mutableStateOf<List<String>?>(null) }

val onNavigatorBack: () -> Unit = {
navigator.navigateBack()
listPaneSelectedFeedUrls = navigator.currentDestination?.content
}

BackHandler(navigator.canNavigateBack()) {
onNavigatorBack()
}

val windowWidth = with(density) { currentWindowSize().width.toDp() }
val feedListWidth by remember(windowWidth) { mutableStateOf(windowWidth * 0.36f) }

ListDetailPaneScaffold(
modifier = Modifier.windowInsetsPadding(WindowInsets.safeDrawing.only(
WindowInsetsSides.Right.run {
Expand All @@ -130,17 +143,21 @@ fun FeedScreen() {
directive = navigator.scaffoldDirective,
value = navigator.scaffoldValue,
listPane = {
AnimatedPane {
AnimatedPane(modifier = Modifier.preferredWidth(feedListWidth)) {
FeedList(
listPaneSelectedFeedUrls = listPaneSelectedFeedUrls,
onShowArticleList = { feedUrls ->
if (navigator.scaffoldDirective.maxHorizontalPartitions > 1) {
navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, feedUrls)
} else {
navController.navigate(R.id.action_to_article_fragment, Bundle().apply {
putStringArrayList(
ArticleFragment.FEED_URLS_KEY, ArrayList(feedUrls),
)
})
navController.navigate(
R.id.action_to_article_fragment,
Bundle().apply {
putStringArrayList(
ArticleFragment.FEED_URLS_KEY, ArrayList(feedUrls),
)
}
)
}
},
)
Expand All @@ -149,7 +166,8 @@ fun FeedScreen() {
detailPane = {
AnimatedPane {
navigator.currentDestination?.content?.let {
ArticleScreen(feedUrls = it, onBackClick = { navigator.navigateBack() })
listPaneSelectedFeedUrls = it
ArticleScreen(feedUrls = it, onBackClick = onNavigatorBack)
}
}
},
Expand All @@ -158,6 +176,7 @@ fun FeedScreen() {

@Composable
private fun FeedList(
listPaneSelectedFeedUrls: List<String>? = null,
onShowArticleList: (List<String>) -> Unit,
viewModel: FeedViewModel = hiltViewModel(),
) {
Expand Down Expand Up @@ -250,6 +269,7 @@ private fun FeedList(
FeedList(
result = groupListState.dataList,
contentPadding = innerPadding + PaddingValues(bottom = fabHeight + 16.dp),
selectedFeedUrls = listPaneSelectedFeedUrls,
onRemoveFeed = { feed -> dispatch(FeedIntent.RemoveFeed(feed.url)) },
onShowArticleList = { feedUrls -> onShowArticleList(feedUrls) },
onEditFeed = { feed ->
Expand Down Expand Up @@ -556,6 +576,7 @@ private fun CreateGroupDialog(
private fun FeedList(
result: List<Any>,
contentPadding: PaddingValues = PaddingValues(),
selectedFeedUrls: List<String>? = null,
onShowArticleList: (List<String>) -> Unit,
onRemoveFeed: (FeedBean) -> Unit,
onEditFeed: (FeedBean) -> Unit,
Expand Down Expand Up @@ -593,7 +614,7 @@ private fun FeedList(
val shouldHideEmptyDefault: (index: Int) -> Boolean = remember(hideEmptyDefault, result) {
{ hideEmptyDefault && result.getOrNull(it + 1) !is FeedViewBean }
}
val adapter = remember(shouldHideEmptyDefault) {
val adapter = remember(shouldHideEmptyDefault, selectedFeedUrls) {
val group1Proxy = Group1Proxy(
isExpand = { feedVisible[it.groupId] ?: false },
onExpandChange = { data, expand -> feedVisible[data.groupId] = expand },
Expand All @@ -620,6 +641,7 @@ private fun FeedList(
group1Proxy,
Feed1Proxy(
visible = { feedVisible[it] ?: false },
selected = { selectedFeedUrls != null && it.url in selectedFeedUrls },
useCardLayout = { true },
onClick = { onShowArticleList(listOf(it.url)) },
isEnded = { it == result.lastIndex || result[it + 1] is GroupBean },
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/com/skyd/anivu/ui/mpv/MPVView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.skyd.anivu.config.Const
import com.skyd.anivu.ext.dataStore
import com.skyd.anivu.ext.getOrDefault
import com.skyd.anivu.model.preference.player.HardwareDecodePreference
import com.skyd.anivu.ui.mpv.controller.bar.toDurationString
import `is`.xyz.mpv.MPVLib
import `is`.xyz.mpv.MPVLib.mpvFormat.MPV_FORMAT_DOUBLE
import `is`.xyz.mpv.MPVLib.mpvFormat.MPV_FORMAT_FLAG
Expand Down Expand Up @@ -165,6 +166,8 @@ class MPVView(context: Context, attrs: AttributeSet?) : SurfaceView(context, att

val subtitleTrack: List<Track>
get() = tracks["sub"].orEmpty().toList()
val audioTrack: List<Track>
get() = tracks["audio"].orEmpty().toList()

private fun getTrackDisplayName(mpvId: Int, lang: String?, title: String?): String {
return if (!lang.isNullOrEmpty() && !title.isNullOrEmpty()) {
Expand Down
28 changes: 28 additions & 0 deletions app/src/main/java/com/skyd/anivu/ui/mpv/PlayerCommand.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.skyd.anivu.ui.mpv

import android.net.Uri
import androidx.compose.ui.geometry.Offset

sealed interface PlayerCommand {
data class SetUri(val uri: Uri) : PlayerCommand
data object Destroy : PlayerCommand
data class Paused(val paused: Boolean) : PlayerCommand
data object GetPaused : PlayerCommand
data object PlayOrPause : PlayerCommand
data class SeekTo(val position: Int) : PlayerCommand
data class Rotate(val rotate: Int) : PlayerCommand
data class Zoom(val zoom: Float) : PlayerCommand
data object GetZoom : PlayerCommand
data class VideoOffset(val offset: Offset) : PlayerCommand
data object GetVideoOffsetX : PlayerCommand
data object GetVideoOffsetY : PlayerCommand
data class SetSpeed(val speed: Float) : PlayerCommand
data object GetSpeed : PlayerCommand
data object LoadAllTracks : PlayerCommand
data object GetSubtitleTrack : PlayerCommand
data class SetSubtitleTrack(val trackId: Int) : PlayerCommand
data object GetAudioTrack : PlayerCommand
data class SetAudioTrack(val trackId: Int) : PlayerCommand
data object Screenshot : PlayerCommand
data class AddSubtitle(val filePath: String) : PlayerCommand
}
Loading

0 comments on commit 3efe7bb

Please sign in to comment.