mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-11-07 03:04:50 +01:00
Several UI/UX minor changes (#1623)
## Description Gathering some smaller UI/UX changes: - Default to the user's preferred subtitle language when searching/downloading subtitles and if unset, fall back to the UI's language - Only show >0s runtime on quick details & don't show negative ends at - On the OS channel row for recently added, only include movies & episodes - Only show movies & episodes to "Recently Added" Android OS channel - Fix context menu for adding songs & albums to the music queue ### Related issues Related to #1339 & #1484 Fixes #1617 Fixes https://github.com/damontecres/Wholphin/issues/1329#issuecomment-4440684328 ### Testing Just on the emulator ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
e5887dfa15
commit
f5ce9745ba
10 changed files with 41 additions and 5 deletions
|
|
@ -160,6 +160,7 @@ data class BaseItem(
|
||||||
data.runTimeTicks
|
data.runTimeTicks
|
||||||
?.ticks
|
?.ticks
|
||||||
?.roundMinutes
|
?.roundMinutes
|
||||||
|
?.takeIf { it > Duration.ZERO }
|
||||||
?.let { add(it.toString()) }
|
?.let { add(it.toString()) }
|
||||||
data.timeRemaining
|
data.timeRemaining
|
||||||
?.roundMinutes
|
?.roundMinutes
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,8 @@ class MusicService
|
||||||
start()
|
start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Timber.w("Tried to add non-audio type %s: %s", item.type, item.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,7 @@ class TvProviderWorker
|
||||||
.getLatestMedia(
|
.getLatestMedia(
|
||||||
GetLatestMediaRequest(
|
GetLatestMediaRequest(
|
||||||
fields = SlimItemFields,
|
fields = SlimItemFields,
|
||||||
|
includeItemTypes = listOf(BaseItemKind.MOVIE, BaseItemKind.EPISODE),
|
||||||
imageTypeLimit = 1,
|
imageTypeLimit = 1,
|
||||||
parentId = null,
|
parentId = null,
|
||||||
groupItems = true,
|
groupItems = true,
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,7 @@ val BaseItemDto.timeRemaining: Duration?
|
||||||
get() =
|
get() =
|
||||||
userData?.playbackPositionTicks?.let {
|
userData?.playbackPositionTicks?.let {
|
||||||
if (it > 0) {
|
if (it > 0) {
|
||||||
runTimeTicks?.minus(it)?.ticks
|
runTimeTicks?.minus(it)?.ticks?.takeIf { it > Duration.ZERO }
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -339,7 +339,8 @@ private fun buildContextMenuItems(
|
||||||
onClickPlayWith: () -> Unit,
|
onClickPlayWith: () -> Unit,
|
||||||
): List<DialogItem> =
|
): List<DialogItem> =
|
||||||
buildList {
|
buildList {
|
||||||
if (showGoTo) {
|
// Songs should not show Go to
|
||||||
|
if (showGoTo && item.type != BaseItemKind.AUDIO) {
|
||||||
add(
|
add(
|
||||||
DialogItem(
|
DialogItem(
|
||||||
resources.getString(R.string.go_to),
|
resources.getString(R.string.go_to),
|
||||||
|
|
@ -466,7 +467,7 @@ private fun buildContextMenuItems(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item.type == BaseItemKind.MUSIC_ALBUM) {
|
if (item.type == BaseItemKind.MUSIC_ALBUM || item.type == BaseItemKind.AUDIO) {
|
||||||
add(
|
add(
|
||||||
DialogItem(
|
DialogItem(
|
||||||
resources.getString(R.string.add_to_queue),
|
resources.getString(R.string.add_to_queue),
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@ class ContextMenuUtils(
|
||||||
onClearChosenStreams = {
|
onClearChosenStreams = {
|
||||||
// Not supported on this page
|
// Not supported on this page
|
||||||
},
|
},
|
||||||
|
onClickAddToQueue = playlistViewModel::addToQueue,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val contextMenu =
|
val contextMenu =
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,19 @@ import android.widget.Toast
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
|
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
|
import com.github.damontecres.wholphin.services.MusicService
|
||||||
import com.github.damontecres.wholphin.services.PlaylistCreator
|
import com.github.damontecres.wholphin.services.PlaylistCreator
|
||||||
import com.github.damontecres.wholphin.ui.detail.PlaylistLoadingState
|
import com.github.damontecres.wholphin.ui.detail.PlaylistLoadingState
|
||||||
|
import com.github.damontecres.wholphin.ui.detail.music.addToQueue
|
||||||
|
import com.github.damontecres.wholphin.ui.launchDefault
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.showToast
|
import com.github.damontecres.wholphin.ui.showToast
|
||||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import org.jellyfin.sdk.api.client.ApiClient
|
||||||
import org.jellyfin.sdk.model.api.MediaType
|
import org.jellyfin.sdk.model.api.MediaType
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
@ -27,7 +32,9 @@ class AddPlaylistViewModel
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
@param:ApplicationContext private val context: Context,
|
@param:ApplicationContext private val context: Context,
|
||||||
|
private val api: ApiClient,
|
||||||
private val playlistCreator: PlaylistCreator,
|
private val playlistCreator: PlaylistCreator,
|
||||||
|
private val musicService: MusicService,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
val playlistState = MutableStateFlow<PlaylistLoadingState>(PlaylistLoadingState.Pending)
|
val playlistState = MutableStateFlow<PlaylistLoadingState>(PlaylistLoadingState.Pending)
|
||||||
|
|
||||||
|
|
@ -72,4 +79,10 @@ class AddPlaylistViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addToQueue(item: BaseItem) {
|
||||||
|
viewModelScope.launchDefault {
|
||||||
|
addToQueue(api, musicService, item, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,3 +147,11 @@ fun ViewModel.addToQueue(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun addToQueue(
|
||||||
|
api: ApiClient,
|
||||||
|
musicService: MusicService,
|
||||||
|
item: BaseItem,
|
||||||
|
index: Int,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ class PlaybackViewModel
|
||||||
val navigationManager: NavigationManager,
|
val navigationManager: NavigationManager,
|
||||||
private val playlistCreator: PlaylistCreator,
|
private val playlistCreator: PlaylistCreator,
|
||||||
private val itemPlaybackDao: ItemPlaybackDao,
|
private val itemPlaybackDao: ItemPlaybackDao,
|
||||||
private val serverRepository: ServerRepository,
|
internal val serverRepository: ServerRepository,
|
||||||
private val itemPlaybackRepository: ItemPlaybackRepository,
|
private val itemPlaybackRepository: ItemPlaybackRepository,
|
||||||
private val playerFactory: PlayerFactory,
|
private val playerFactory: PlayerFactory,
|
||||||
private val datePlayedService: DatePlayedService,
|
private val datePlayedService: DatePlayedService,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import com.github.damontecres.wholphin.R
|
||||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
import com.github.damontecres.wholphin.data.model.PlaylistItem
|
import com.github.damontecres.wholphin.data.model.PlaylistItem
|
||||||
import com.github.damontecres.wholphin.data.model.TrackIndex
|
import com.github.damontecres.wholphin.data.model.TrackIndex
|
||||||
|
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.onMain
|
import com.github.damontecres.wholphin.ui.onMain
|
||||||
import com.github.damontecres.wholphin.ui.showToast
|
import com.github.damontecres.wholphin.ui.showToast
|
||||||
|
|
@ -41,7 +42,15 @@ sealed interface SubtitleSearchStatus {
|
||||||
/**
|
/**
|
||||||
* Trigger a search for subtitles in the given language for the currently playing media
|
* Trigger a search for subtitles in the given language for the currently playing media
|
||||||
*/
|
*/
|
||||||
fun PlaybackViewModel.searchForSubtitles(language: String = Locale.current.language) {
|
fun PlaybackViewModel.searchForSubtitles(
|
||||||
|
language: String =
|
||||||
|
serverRepository
|
||||||
|
.currentUserDto
|
||||||
|
?.configuration
|
||||||
|
?.subtitleLanguagePreference
|
||||||
|
?.takeIf { it.isNotNullOrBlank() }
|
||||||
|
?: Locale.current.language,
|
||||||
|
) {
|
||||||
subtitleSearchState.update {
|
subtitleSearchState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
status = SubtitleSearchStatus.Searching,
|
status = SubtitleSearchStatus.Searching,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue