mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 08:01:20 +02:00
Updates to buttons
This commit is contained in:
parent
6046799b91
commit
f27415de0f
6 changed files with 104 additions and 44 deletions
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
||||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
import com.github.damontecres.wholphin.data.model.NavDrawerPinnedItem
|
import com.github.damontecres.wholphin.data.model.NavDrawerPinnedItem
|
||||||
import com.github.damontecres.wholphin.data.model.NavPinType
|
import com.github.damontecres.wholphin.data.model.NavPinType
|
||||||
|
import com.github.damontecres.wholphin.services.SeerrServerRepository
|
||||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
import com.github.damontecres.wholphin.ui.nav.NavDrawerItem
|
import com.github.damontecres.wholphin.ui.nav.NavDrawerItem
|
||||||
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
|
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
|
||||||
|
|
@ -24,6 +25,7 @@ class NavDrawerItemRepository
|
||||||
private val api: ApiClient,
|
private val api: ApiClient,
|
||||||
private val serverRepository: ServerRepository,
|
private val serverRepository: ServerRepository,
|
||||||
private val serverPreferencesDao: ServerPreferencesDao,
|
private val serverPreferencesDao: ServerPreferencesDao,
|
||||||
|
private val seerrServerRepository: SeerrServerRepository,
|
||||||
) {
|
) {
|
||||||
suspend fun getNavDrawerItems(): List<NavDrawerItem> {
|
suspend fun getNavDrawerItems(): List<NavDrawerItem> {
|
||||||
val user = serverRepository.currentUser.value
|
val user = serverRepository.currentUser.value
|
||||||
|
|
@ -46,7 +48,13 @@ class NavDrawerItemRepository
|
||||||
setOf()
|
setOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
val builtins = listOf(NavDrawerItem.Favorites, NavDrawerItem.Discover)
|
val builtins =
|
||||||
|
if (seerrServerRepository.active()) {
|
||||||
|
listOf(NavDrawerItem.Favorites, NavDrawerItem.Discover)
|
||||||
|
} else {
|
||||||
|
listOf(NavDrawerItem.Favorites)
|
||||||
|
}
|
||||||
|
|
||||||
val libraries =
|
val libraries =
|
||||||
userViews
|
userViews
|
||||||
.filter { it.collectionType in supportedCollectionTypes || it.id in recordingFolders }
|
.filter { it.collectionType in supportedCollectionTypes || it.id in recordingFolders }
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import dagger.hilt.android.scopes.ActivityScoped
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
@ -51,6 +52,11 @@ class SeerrServerRepository
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether Seerr integration is currently active of not
|
||||||
|
*/
|
||||||
|
suspend fun active(): Boolean = current.firstOrNull() != null && seerrApi.active
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
_currentServer.update { null }
|
_currentServer.update { null }
|
||||||
_currentUser.update { null }
|
_currentUser.update { null }
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||||
|
import org.jellyfin.sdk.model.serializer.toUUIDOrNull
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DiscoverMovieDetails(
|
fun DiscoverMovieDetails(
|
||||||
|
|
@ -142,6 +144,16 @@ fun DiscoverMovieDetails(
|
||||||
files = listOf(),
|
files = listOf(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
goToOnClick = {
|
||||||
|
movie.mediaInfo?.jellyfinMediaId?.toUUIDOrNull()?.let {
|
||||||
|
viewModel.navigateTo(
|
||||||
|
Destination.MediaItem(
|
||||||
|
itemId = it,
|
||||||
|
type = BaseItemKind.MOVIE,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
moreOnClick = {
|
moreOnClick = {
|
||||||
moreDialog =
|
moreDialog =
|
||||||
DialogParams(
|
DialogParams(
|
||||||
|
|
@ -214,6 +226,7 @@ fun DiscoverMovieDetailsContent(
|
||||||
cancelOnClick: () -> Unit,
|
cancelOnClick: () -> Unit,
|
||||||
trailerOnClick: (Trailer) -> Unit,
|
trailerOnClick: (Trailer) -> Unit,
|
||||||
overviewOnClick: () -> Unit,
|
overviewOnClick: () -> Unit,
|
||||||
|
goToOnClick: () -> Unit,
|
||||||
moreOnClick: () -> Unit,
|
moreOnClick: () -> Unit,
|
||||||
onClickItem: (Int, DiscoverItem) -> Unit,
|
onClickItem: (Int, DiscoverItem) -> Unit,
|
||||||
onClickPerson: (Person) -> Unit,
|
onClickPerson: (Person) -> Unit,
|
||||||
|
|
@ -262,6 +275,7 @@ fun DiscoverMovieDetailsContent(
|
||||||
requestOnClick = requestOnClick,
|
requestOnClick = requestOnClick,
|
||||||
cancelOnClick = cancelOnClick,
|
cancelOnClick = cancelOnClick,
|
||||||
moreOnClick = moreOnClick,
|
moreOnClick = moreOnClick,
|
||||||
|
goToOnClick = goToOnClick,
|
||||||
buttonOnFocusChanged = {
|
buttonOnFocusChanged = {
|
||||||
if (it.isFocused) {
|
if (it.isFocused) {
|
||||||
position = HEADER_ROW
|
position = HEADER_ROW
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import androidx.compose.foundation.lazy.LazyRow
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.MoreVert
|
import androidx.compose.material.icons.filled.MoreVert
|
||||||
import androidx.compose.material.icons.filled.PlayArrow
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
|
@ -28,6 +27,7 @@ fun ExpandableDiscoverButtons(
|
||||||
availability: SeerrAvailability,
|
availability: SeerrAvailability,
|
||||||
requestOnClick: () -> Unit,
|
requestOnClick: () -> Unit,
|
||||||
cancelOnClick: () -> Unit,
|
cancelOnClick: () -> Unit,
|
||||||
|
goToOnClick: () -> Unit,
|
||||||
moreOnClick: () -> Unit,
|
moreOnClick: () -> Unit,
|
||||||
buttonOnFocusChanged: (FocusState) -> Unit,
|
buttonOnFocusChanged: (FocusState) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
@ -41,32 +41,71 @@ fun ExpandableDiscoverButtons(
|
||||||
.focusGroup()
|
.focusGroup()
|
||||||
.focusRestorer(firstFocus),
|
.focusRestorer(firstFocus),
|
||||||
) {
|
) {
|
||||||
if (availability == SeerrAvailability.UNKNOWN) {
|
val text =
|
||||||
item("first") {
|
when (availability) {
|
||||||
ExpandableFaButton(
|
SeerrAvailability.UNKNOWN -> R.string.request
|
||||||
title = R.string.request,
|
|
||||||
iconStringRes = R.string.fa_download,
|
SeerrAvailability.PENDING,
|
||||||
onClick = requestOnClick,
|
SeerrAvailability.PROCESSING,
|
||||||
modifier =
|
-> R.string.pending
|
||||||
Modifier
|
|
||||||
.focusRequester(firstFocus)
|
SeerrAvailability.PARTIALLY_AVAILABLE,
|
||||||
.onFocusChanged(buttonOnFocusChanged),
|
SeerrAvailability.AVAILABLE,
|
||||||
)
|
-> R.string.go_to
|
||||||
|
|
||||||
|
SeerrAvailability.DELETED -> R.string.delete // TODO
|
||||||
}
|
}
|
||||||
} else if (availability == SeerrAvailability.PENDING || availability == SeerrAvailability.PROCESSING) {
|
val icon =
|
||||||
item("first") {
|
when (availability) {
|
||||||
ExpandableFaButton(
|
SeerrAvailability.UNKNOWN -> R.string.fa_download
|
||||||
title = R.string.pending,
|
|
||||||
iconStringRes = R.string.fa_clock,
|
SeerrAvailability.PENDING,
|
||||||
onClick = {
|
SeerrAvailability.PROCESSING,
|
||||||
// TODO show request dialog?
|
-> R.string.fa_clock
|
||||||
},
|
|
||||||
modifier =
|
SeerrAvailability.PARTIALLY_AVAILABLE,
|
||||||
Modifier
|
SeerrAvailability.AVAILABLE,
|
||||||
.focusRequester(firstFocus)
|
-> R.string.fa_play
|
||||||
.onFocusChanged(buttonOnFocusChanged),
|
|
||||||
)
|
SeerrAvailability.DELETED -> R.string.fa_video // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item("first") {
|
||||||
|
ExpandableFaButton(
|
||||||
|
title = text,
|
||||||
|
iconStringRes = icon,
|
||||||
|
onClick = {
|
||||||
|
when (availability) {
|
||||||
|
SeerrAvailability.UNKNOWN -> {
|
||||||
|
requestOnClick.invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
SeerrAvailability.PENDING,
|
||||||
|
SeerrAvailability.PROCESSING,
|
||||||
|
-> {
|
||||||
|
cancelOnClick.invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
SeerrAvailability.PARTIALLY_AVAILABLE,
|
||||||
|
SeerrAvailability.AVAILABLE,
|
||||||
|
-> {
|
||||||
|
goToOnClick.invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
SeerrAvailability.DELETED -> {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.focusRequester(firstFocus)
|
||||||
|
.onFocusChanged(buttonOnFocusChanged),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (availability == SeerrAvailability.PENDING || availability == SeerrAvailability.PROCESSING) {
|
||||||
|
// TODO should only show if user can cancel
|
||||||
item("cancel") {
|
item("cancel") {
|
||||||
ExpandablePlayButton(
|
ExpandablePlayButton(
|
||||||
title = R.string.cancel,
|
title = R.string.cancel,
|
||||||
|
|
@ -78,21 +117,6 @@ fun ExpandableDiscoverButtons(
|
||||||
.onFocusChanged(buttonOnFocusChanged),
|
.onFocusChanged(buttonOnFocusChanged),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (availability == SeerrAvailability.PARTIALLY_AVAILABLE || availability == SeerrAvailability.AVAILABLE) {
|
|
||||||
item("first") {
|
|
||||||
ExpandablePlayButton(
|
|
||||||
title = R.string.go_to,
|
|
||||||
icon = Icons.Default.PlayArrow,
|
|
||||||
onClick = {
|
|
||||||
// TODO go to the item
|
|
||||||
},
|
|
||||||
resume = Duration.ZERO,
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.focusRequester(firstFocus)
|
|
||||||
.onFocusChanged(buttonOnFocusChanged),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// More button
|
// More button
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ class NavDrawerViewModel
|
||||||
val setupNavigationManager: SetupNavigationManager,
|
val setupNavigationManager: SetupNavigationManager,
|
||||||
val backdropService: BackdropService,
|
val backdropService: BackdropService,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private var all: List<NavDrawerItem>? = null
|
// private var all: List<NavDrawerItem>? = null
|
||||||
val moreLibraries = MutableLiveData<List<NavDrawerItem>>(null)
|
val moreLibraries = MutableLiveData<List<NavDrawerItem>>(null)
|
||||||
val libraries = MutableLiveData<List<NavDrawerItem>>(listOf())
|
val libraries = MutableLiveData<List<NavDrawerItem>>(listOf())
|
||||||
val selectedIndex = MutableLiveData(-1)
|
val selectedIndex = MutableLiveData(-1)
|
||||||
|
|
@ -119,8 +119,8 @@ class NavDrawerViewModel
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
viewModelScope.launchIO {
|
viewModelScope.launchIO {
|
||||||
val all = all ?: navDrawerItemRepository.getNavDrawerItems()
|
val all = navDrawerItemRepository.getNavDrawerItems()
|
||||||
this@NavDrawerViewModel.all = all
|
// this@NavDrawerViewModel.all = all
|
||||||
val libraries = navDrawerItemRepository.getFilteredNavDrawerItems(all)
|
val libraries = navDrawerItemRepository.getFilteredNavDrawerItems(all)
|
||||||
val moreLibraries = all.toMutableList().apply { removeAll(libraries) }
|
val moreLibraries = all.toMutableList().apply { removeAll(libraries) }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,13 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
|
|
@ -26,6 +30,7 @@ import com.github.damontecres.wholphin.ui.cards.ItemRow
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
import com.github.damontecres.wholphin.ui.setValueOnMain
|
import com.github.damontecres.wholphin.ui.setValueOnMain
|
||||||
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import org.jellyfin.sdk.api.client.ApiClient
|
import org.jellyfin.sdk.api.client.ApiClient
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -75,6 +80,8 @@ fun SeerrDiscoverPage(
|
||||||
val movies by viewModel.discoverMovies.observeAsState(listOf())
|
val movies by viewModel.discoverMovies.observeAsState(listOf())
|
||||||
val tv by viewModel.discoverTv.observeAsState(listOf())
|
val tv by viewModel.discoverTv.observeAsState(listOf())
|
||||||
|
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
LaunchedEffect(movies) { if (movies.isNotEmpty()) focusRequester.tryRequestFocus() }
|
||||||
val scrollState = rememberScrollState()
|
val scrollState = rememberScrollState()
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
|
@ -99,6 +106,7 @@ fun SeerrDiscoverPage(
|
||||||
modifier = mod,
|
modifier = mod,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
modifier = Modifier.focusRequester(focusRequester),
|
||||||
)
|
)
|
||||||
ItemRow(
|
ItemRow(
|
||||||
title = stringResource(R.string.tv_shows),
|
title = stringResource(R.string.tv_shows),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue