Skip to content

Commit

Permalink
Tries to fix most of the video related issues
Browse files Browse the repository at this point in the history
Fixes [BUG] Cannot Zoom Into Picture #560
Fixes [BUG] videos don't play in the last two versions of the app #559
Fixes [Enhancement] Disable video auto play option #555
Fixes [BUG] Can play video from previous picture #530

Signed-off-by: IacobIonut01 <[email protected]>
  • Loading branch information
IacobIonut01 committed Dec 17, 2024
1 parent 7f4a912 commit 593bc67
Show file tree
Hide file tree
Showing 11 changed files with 247 additions and 189 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ android {
applicationId = "com.dot.gallery"
minSdk = 30
targetSdk = 35
versionCode = 31020
versionName = "3.1.0"
versionCode = 31105
versionName = "3.1.1"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/kotlin/com/dot/gallery/core/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,12 @@ object Settings {
rememberPreference(key = WEEKLY_DATE_FORMAT, defaultValue = Constants.WEEKLY_DATE_FORMAT)

fun getSetting(context: Context, key: Preferences.Key<String>) = context.dataStore.data.map { it[key] }

private val VIDEO_AUTOPLAY = booleanPreferencesKey("video_autoplay")

@Composable
fun rememberVideoAutoplay() =
rememberPreference(key = VIDEO_AUTOPLAY, defaultValue = true)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import kotlin.math.roundToInt
@Composable
fun Modifier.swipe(
enabled: Boolean = true,
onOffset: (IntOffset) -> Unit = {},
onSwipeDown: () -> Unit
): Modifier {
var delta by remember { mutableFloatStateOf(0f) }
Expand Down Expand Up @@ -66,6 +67,6 @@ fun Modifier.swipe(
}
}
.offset {
IntOffset(0, if (isDragging) delta.roundToInt() else animatedDelta.roundToInt())
IntOffset(0, if (isDragging) delta.roundToInt() else animatedDelta.roundToInt()).also(onOffset)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dot.gallery.feature_node.presentation.library

import android.os.Build
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
Expand Down Expand Up @@ -184,17 +185,19 @@ fun LibraryScreen(
Alignment.CenterHorizontally
)
) {
LibrarySmallItem(
title = stringResource(R.string.vault),
icon = GalleryIcons.Encrypted,
contentColor = MaterialTheme.colorScheme.secondary,
modifier = Modifier
.weight(1f)
.clickable {
navigate(Screen.VaultScreen())
},
contentDescription = stringResource(R.string.vault)
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
LibrarySmallItem(
title = stringResource(R.string.vault),
icon = GalleryIcons.Encrypted,
contentColor = MaterialTheme.colorScheme.secondary,
modifier = Modifier
.weight(1f)
.clickable {
navigate(Screen.VaultScreen())
},
contentDescription = stringResource(R.string.vault)
)
}
LibrarySmallItem(
title = stringResource(R.string.ignored),
icon = Icons.Outlined.VisibilityOff,
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -682,10 +682,8 @@ private fun <T : Media> MediaViewInfoActions2(

@Composable
fun <T : Media> MediaViewActions2(
currentIndex: Int,
currentMedia: T?,
handler: MediaHandleUseCase?,
onDeleteMedia: ((Int) -> Unit)?,
showDeleteButton: Boolean,
enabled: Boolean,
deleteMedia: ((Vault, T, () -> Unit) -> Unit)?,
Expand All @@ -703,7 +701,6 @@ fun <T : Media> MediaViewActions2(
enabled = enabled
) {
scope.launch {
onDeleteMedia?.invoke(currentIndex)
handler!!.trashMedia(result = result, arrayListOf(it), trash = false)
}
}
Expand All @@ -715,7 +712,6 @@ fun <T : Media> MediaViewActions2(
enabled = enabled
) {
scope.launch {
onDeleteMedia?.invoke(currentIndex)
handler!!.deleteMedia(result = result, arrayListOf(it))
}
}
Expand All @@ -733,14 +729,12 @@ fun <T : Media> MediaViewActions2(
// Trash Component
if (showDeleteButton) {
TrashButton(
currentIndex,
currentMedia,
handler,
false,
media = currentMedia,
handler = handler,
followTheme = false,
enabled = enabled,
onDeleteMedia,
currentVault = currentVault,
deleteMedia = deleteMedia
deleteMedia = deleteMedia,
currentVault = currentVault
)
}
}
Expand Down Expand Up @@ -990,12 +984,10 @@ fun <T : Media> OpenAsButton(

@Composable
fun <T : Media> TrashButton(
index: Int,
media: T,
handler: MediaHandleUseCase?,
followTheme: Boolean = false,
enabled: Boolean,
onDeleteMedia: ((Int) -> Unit)?,
deleteMedia: ((Vault, T, () -> Unit) -> Unit)?,
currentVault: Vault?
) {
Expand All @@ -1010,7 +1002,6 @@ fun <T : Media> TrashButton(
scope.launch {
state.hide()
shouldMoveToTrash = true
onDeleteMedia?.invoke(index)
}
}
BottomBarColumn(
Expand Down Expand Up @@ -1040,9 +1031,7 @@ fun <T : Media> TrashButton(
) {
if (deleteMedia != null && currentVault != null) {
it.forEach { media ->
deleteMedia(currentVault, media) {
onDeleteMedia?.invoke(index)
}
deleteMedia(currentVault, media) {}
}
} else {
if (shouldMoveToTrash) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableLongState
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.NonRestartableComposable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.IntOffset
import androidx.media3.exoplayer.ExoPlayer
import com.dot.gallery.feature_node.domain.model.Media
import com.dot.gallery.feature_node.domain.util.isVideo
Expand All @@ -27,14 +30,15 @@ import com.dot.gallery.feature_node.presentation.mediaview.components.video.Vide
fun <T: Media> MediaPreviewComponent(
media: T?,
uiEnabled: Boolean,
playWhenReady: Boolean,
playWhenReady: State<Boolean>,
onItemClick: () -> Unit,
onSwipeDown: () -> Unit,
offset: IntOffset,
videoController: @Composable (ExoPlayer, MutableState<Boolean>, MutableLongState, Long, Int, Float) -> Unit,
) {
if (media != null) {
Box(
modifier = Modifier.fillMaxSize(),
modifier = Modifier.fillMaxSize().offset { offset },
) {
AnimatedVisibility(
modifier = Modifier.fillMaxSize(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.runtime.MutableLongState
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.NonRestartableComposable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableLongStateOf
Expand All @@ -28,6 +29,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
Expand All @@ -54,18 +56,22 @@ import io.sanghun.compose.video.VideoPlayer as SanghunComposeVideoVideoPlayer
@androidx.annotation.OptIn(UnstableApi::class)
@NonRestartableComposable
@Composable
fun <T: Media> VideoPlayer(
fun <T : Media> VideoPlayer(
media: T,
playWhenReady: Boolean,
playWhenReady: State<Boolean>,
videoController: @Composable (ExoPlayer, MutableState<Boolean>, MutableLongState, Long, Int, Float) -> Unit,
onItemClick: () -> Unit,
onSwipeDown: () -> Unit
) {
var totalDuration by rememberSaveable { mutableLongStateOf(0L) }
val currentTime = rememberSaveable { mutableLongStateOf(0L) }
var bufferedPercentage by rememberSaveable { mutableIntStateOf(0) }
val isPlaying = rememberSaveable(playWhenReady) { mutableStateOf(playWhenReady) }
var lastPlayingState by rememberSaveable(isPlaying.value) { mutableStateOf(isPlaying.value) }
var totalDuration by rememberSaveable(media) { mutableLongStateOf(0L) }
val currentTime = rememberSaveable(media) { mutableLongStateOf(0L) }
var bufferedPercentage by rememberSaveable(media) { mutableIntStateOf(0) }
val isPlaying =
rememberSaveable(playWhenReady.value, media) { mutableStateOf(playWhenReady.value) }
var lastPlayingState by rememberSaveable(
isPlaying.value,
media
) { mutableStateOf(isPlaying.value) }
val context = LocalContext.current
val keychainHolder = remember {
KeychainHolder(context)
Expand Down Expand Up @@ -116,8 +122,16 @@ fun <T: Media> VideoPlayer(
mutableStateOf<ExoPlayer?>(null)
}

LaunchedEffect(exoPlayer, playWhenReady.value) {
exoPlayer?.let { player ->
if (player.playWhenReady != playWhenReady.value) {
player.playWhenReady = playWhenReady.value
}
}
}

var showPlayer by remember {
mutableStateOf(false)
mutableStateOf(true)
}
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(lifecycleOwner) {
Expand All @@ -134,11 +148,15 @@ fun <T: Media> VideoPlayer(
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
LaunchedEffect(showPlayer) {
if (showPlayer) {
delay(100)
exoPlayer?.playWhenReady = isPlaying.value
exoPlayer?.seekTo(currentTime.longValue)
LaunchedEffect(LocalConfiguration.current.orientation) {
exoPlayer?.let {
if (it.currentPosition != currentTime.longValue) {
delay(100)
it.seekTo(currentTime.longValue)
if (lastPlayingState) {
it.play()
}
}
}
}

Expand All @@ -163,22 +181,30 @@ fun <T: Media> VideoPlayer(
}
},
handleLifecycle = true,
autoPlay = playWhenReady,
autoPlay = playWhenReady.value,
usePlayerController = false,
enablePip = false,
handleAudioFocus = audioFocus,
repeatMode = RepeatMode.ONE,
playerInstance = {
exoPlayer = this
addListener(
object : Player.Listener {
override fun onEvents(player: Player, events: Player.Events) {
totalDuration = duration.coerceAtLeast(0L)
lastPlayingState = isPlaying.value
isPlaying.value = player.isPlaying
}

override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) {
super.onPlayWhenReadyChanged(playWhenReady, reason)
isPlaying.value = playWhenReady
}

override fun onIsPlayingChanged(isPlaying: Boolean) {
super.onIsPlayingChanged(isPlaying)
lastPlayingState = isPlaying
}
}
)
exoPlayer = this
},
modifier = Modifier
.fillMaxSize()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.media3.exoplayer.ExoPlayer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import com.dot.gallery.core.Settings.Misc.rememberAutoHideSearchBar
import com.dot.gallery.core.Settings.Misc.rememberForcedLastScreen
import com.dot.gallery.core.Settings.Misc.rememberFullBrightnessView
import com.dot.gallery.core.Settings.Misc.rememberLastScreen
import com.dot.gallery.core.Settings.Misc.rememberVideoAutoplay
import com.dot.gallery.core.SettingsEntity
import com.dot.gallery.feature_node.presentation.settings.components.SettingsAppHeader
import com.dot.gallery.feature_node.presentation.settings.components.SettingsItem
Expand Down Expand Up @@ -431,6 +432,17 @@ fun rememberSettingsList(
summary = context.getString(R.string.auto_hide_on_video_play_summary),
isChecked = autoHideOnVideoPlay,
onCheck = { autoHideOnVideoPlay = it },
screenPosition = Position.Middle
)
}

var autoPlayVideo by rememberVideoAutoplay()
val autoPlayVideoPref = remember(autoPlayVideo) {
SettingsEntity.SwitchPreference(
title = context.getString(R.string.auto_play_video),
summary = context.getString(R.string.auto_play_video_summary),
isChecked = autoPlayVideo,
onCheck = { autoPlayVideo = it },
screenPosition = Position.Bottom
)
}
Expand Down Expand Up @@ -495,6 +507,7 @@ fun rememberSettingsList(
add(audioFocusPref)
add(fullBrightnessViewPref)
add(autoHideOnVideoPlayPref)
add(autoPlayVideoPref)
/** ********************* **/
/** ********************* **/
/** Navigation Section Start **/
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@
<string name="media_grid">Media Grid</string>
<string name="classic_date">Classic Date</string>
<string name="extended_date">Extended Date</string>
<string name="auto_play_video">Video Auto-Play</string>
<string name="auto_play_video_summary">Play the video automatically while viewing media</string>
<plurals name="item_count">
<item quantity="one">%s item</item>
<item quantity="other">%s items</item>
Expand Down

0 comments on commit 593bc67

Please sign in to comment.