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
|
||||
?.ticks
|
||||
?.roundMinutes
|
||||
?.takeIf { it > Duration.ZERO }
|
||||
?.let { add(it.toString()) }
|
||||
data.timeRemaining
|
||||
?.roundMinutes
|
||||
|
|
|
|||
|
|
@ -228,6 +228,8 @@ class MusicService
|
|||
start()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.w("Tried to add non-audio type %s: %s", item.type, item.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -264,6 +264,7 @@ class TvProviderWorker
|
|||
.getLatestMedia(
|
||||
GetLatestMediaRequest(
|
||||
fields = SlimItemFields,
|
||||
includeItemTypes = listOf(BaseItemKind.MOVIE, BaseItemKind.EPISODE),
|
||||
imageTypeLimit = 1,
|
||||
parentId = null,
|
||||
groupItems = true,
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ val BaseItemDto.timeRemaining: Duration?
|
|||
get() =
|
||||
userData?.playbackPositionTicks?.let {
|
||||
if (it > 0) {
|
||||
runTimeTicks?.minus(it)?.ticks
|
||||
runTimeTicks?.minus(it)?.ticks?.takeIf { it > Duration.ZERO }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -339,7 +339,8 @@ private fun buildContextMenuItems(
|
|||
onClickPlayWith: () -> Unit,
|
||||
): List<DialogItem> =
|
||||
buildList {
|
||||
if (showGoTo) {
|
||||
// Songs should not show Go to
|
||||
if (showGoTo && item.type != BaseItemKind.AUDIO) {
|
||||
add(
|
||||
DialogItem(
|
||||
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(
|
||||
DialogItem(
|
||||
resources.getString(R.string.add_to_queue),
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ class ContextMenuUtils(
|
|||
onClearChosenStreams = {
|
||||
// Not supported on this page
|
||||
},
|
||||
onClickAddToQueue = playlistViewModel::addToQueue,
|
||||
)
|
||||
}
|
||||
val contextMenu =
|
||||
|
|
|
|||
|
|
@ -5,14 +5,19 @@ import android.widget.Toast
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
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.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.showToast
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.model.api.MediaType
|
||||
import timber.log.Timber
|
||||
import java.util.UUID
|
||||
|
|
@ -27,7 +32,9 @@ class AddPlaylistViewModel
|
|||
@Inject
|
||||
constructor(
|
||||
@param:ApplicationContext private val context: Context,
|
||||
private val api: ApiClient,
|
||||
private val playlistCreator: PlaylistCreator,
|
||||
private val musicService: MusicService,
|
||||
) : ViewModel() {
|
||||
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,
|
||||
private val playlistCreator: PlaylistCreator,
|
||||
private val itemPlaybackDao: ItemPlaybackDao,
|
||||
private val serverRepository: ServerRepository,
|
||||
internal val serverRepository: ServerRepository,
|
||||
private val itemPlaybackRepository: ItemPlaybackRepository,
|
||||
private val playerFactory: PlayerFactory,
|
||||
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.PlaylistItem
|
||||
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.onMain
|
||||
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
|
||||
*/
|
||||
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 {
|
||||
it.copy(
|
||||
status = SubtitleSearchStatus.Searching,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue