Merge Wholphin v1.1.0 while preserving Wolfskin features #27
4 changed files with 397 additions and 725 deletions
|
|
@ -44,7 +44,6 @@ import com.github.damontecres.wholphin.ui.detail.CardGrid
|
|||
import com.github.damontecres.wholphin.ui.detail.GridItemDetails
|
||||
import com.github.damontecres.wholphin.ui.ifElse
|
||||
import com.github.damontecres.wholphin.ui.main.HomePageHeader
|
||||
import com.github.damontecres.wholphin.ui.playback.scale
|
||||
import com.github.damontecres.wholphin.ui.util.ScrollToTopBringIntoViewSpec
|
||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||
import org.jellyfin.sdk.model.api.CollectionType
|
||||
|
|
@ -53,19 +52,18 @@ import kotlin.time.Duration
|
|||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun CollectionFolderGrid(
|
||||
fun CollectionFolderViewScope.CollectionFolderGrid(
|
||||
preferences: UserPreferences,
|
||||
collectionType: CollectionType?,
|
||||
focusedItem: BaseItem?,
|
||||
items: List<BaseItem?>,
|
||||
sortAndDirection: SortAndDirection,
|
||||
onClickItem: (Int, BaseItem) -> Unit,
|
||||
onLongClickItem: (Int, BaseItem) -> Unit,
|
||||
letterPosition: suspend (Char) -> Int,
|
||||
viewOptions: ViewOptions,
|
||||
onClickPlay: (Int, BaseItem) -> Unit,
|
||||
initialPosition: Int,
|
||||
gridFocusRequester: FocusRequester,
|
||||
cardContent: @Composable CollectionFolderViewScope.(GridItemDetails<BaseItem>) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
||||
) {
|
||||
|
|
@ -99,18 +97,8 @@ fun CollectionFolderGrid(
|
|||
modifier = Modifier.fillMaxSize(),
|
||||
initialPosition = initialPosition,
|
||||
positionCallback = positionCallback,
|
||||
cardContent = { (item, index, onClick, onLongClick, widthPx, mod) ->
|
||||
GridCard(
|
||||
item = item,
|
||||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
imageContentScale = viewOptions.contentScale.scale,
|
||||
imageAspectRatio = viewOptions.aspectRatio.ratio,
|
||||
imageType = viewOptions.imageType,
|
||||
showTitle = viewOptions.showTitles,
|
||||
fillWidth = widthPx,
|
||||
modifier = mod,
|
||||
)
|
||||
cardContent = { details ->
|
||||
cardContent.invoke(this@CollectionFolderGrid, details)
|
||||
},
|
||||
columns = viewOptions.columns,
|
||||
spacing = viewOptions.spacing.dp,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
|
|
@ -59,6 +60,7 @@ import com.github.damontecres.wholphin.ui.cards.FavoriteIndicator
|
|||
import com.github.damontecres.wholphin.ui.cards.WatchedIcon
|
||||
import com.github.damontecres.wholphin.ui.data.SortAndDirection
|
||||
import com.github.damontecres.wholphin.ui.detail.AlphabetButtons
|
||||
import com.github.damontecres.wholphin.ui.detail.GridItemDetails
|
||||
import com.github.damontecres.wholphin.ui.enableMarquee
|
||||
import com.github.damontecres.wholphin.ui.formatDuration
|
||||
import com.github.damontecres.wholphin.ui.ifElse
|
||||
|
|
@ -75,7 +77,7 @@ import org.jellyfin.sdk.model.api.ItemSortBy
|
|||
import org.jellyfin.sdk.model.extensions.ticks
|
||||
|
||||
@Composable
|
||||
fun CollectionFolderList(
|
||||
fun CollectionFolderViewScope.CollectionFolderList(
|
||||
preferences: UserPreferences,
|
||||
collectionType: CollectionType?,
|
||||
focusedItem: BaseItem?,
|
||||
|
|
@ -84,10 +86,10 @@ fun CollectionFolderList(
|
|||
onClickItem: (Int, BaseItem) -> Unit,
|
||||
onLongClickItem: (Int, BaseItem) -> Unit,
|
||||
letterPosition: suspend (Char) -> Int,
|
||||
viewOptions: ViewOptions,
|
||||
onClickPlay: (Int, BaseItem) -> Unit,
|
||||
initialPosition: Int,
|
||||
gridFocusRequester: FocusRequester,
|
||||
itemContent: @Composable CollectionFolderViewScope.(GridItemDetails<BaseItem>) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
||||
) {
|
||||
|
|
@ -153,10 +155,8 @@ fun CollectionFolderList(
|
|||
).padding(8.dp),
|
||||
)
|
||||
}
|
||||
CollectionFolderContent(
|
||||
this@CollectionFolderList.CollectionFolderListContent(
|
||||
items = items,
|
||||
viewOptions = viewOptions,
|
||||
collectionType = collectionType,
|
||||
listState = listState,
|
||||
position = position,
|
||||
positionFocusRequester = positionFocusRequester,
|
||||
|
|
@ -167,6 +167,7 @@ fun CollectionFolderList(
|
|||
},
|
||||
onClickItem = onClickItem,
|
||||
onLongClickItem = onLongClickItem,
|
||||
itemContent = itemContent,
|
||||
modifier =
|
||||
Modifier
|
||||
.weight(1f)
|
||||
|
|
@ -266,44 +267,43 @@ fun CollectionFolderListDetails(
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun CollectionFolderContent(
|
||||
fun CollectionFolderViewScope.CollectionFolderListContent(
|
||||
items: List<BaseItem?>,
|
||||
viewOptions: ViewOptions,
|
||||
collectionType: CollectionType?,
|
||||
listState: LazyListState,
|
||||
position: Int,
|
||||
positionFocusRequester: FocusRequester,
|
||||
onClickItem: (Int, BaseItem) -> Unit,
|
||||
onLongClickItem: (Int, BaseItem) -> Unit,
|
||||
onPositionChange: (Int) -> Unit,
|
||||
itemContent: @Composable CollectionFolderViewScope.(GridItemDetails<BaseItem>) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val currentPosition by rememberUpdatedState(position)
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
verticalArrangement = Arrangement.spacedBy(viewOptions.spacing.dp),
|
||||
modifier = modifier.focusRestorer(positionFocusRequester),
|
||||
) {
|
||||
itemsIndexed(items) { index, item ->
|
||||
val onClick: () -> Unit =
|
||||
remember(index, item) {
|
||||
{ item?.let { onClickItem.invoke(index, item) } }
|
||||
val details =
|
||||
remember(item, index, onClickItem, onLongClickItem, onPositionChange) {
|
||||
GridItemDetails(
|
||||
item = item,
|
||||
index = index,
|
||||
onClick = { item?.let { onClickItem.invoke(index, item) } },
|
||||
onLongClick = { item?.let { onLongClickItem.invoke(index, item) } },
|
||||
widthPx = -1,
|
||||
mod =
|
||||
Modifier
|
||||
.onFocusChanged {
|
||||
if (it.isFocused) onPositionChange.invoke(index)
|
||||
}.ifElse(
|
||||
index == currentPosition,
|
||||
Modifier.focusRequester(positionFocusRequester),
|
||||
),
|
||||
)
|
||||
}
|
||||
val onLongClick: () -> Unit =
|
||||
remember(index, item) {
|
||||
{ item?.let { onLongClickItem.invoke(index, item) } }
|
||||
}
|
||||
CollectionFolderListItem(
|
||||
item = item,
|
||||
dense = viewOptions.type == ViewOptionsType.DENSE_LIST,
|
||||
collectionType = collectionType,
|
||||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
modifier =
|
||||
Modifier
|
||||
.onFocusChanged {
|
||||
if (it.isFocused) onPositionChange.invoke(index)
|
||||
}.ifElse(index == position, Modifier.focusRequester(positionFocusRequester)),
|
||||
)
|
||||
itemContent.invoke(this@CollectionFolderListContent, details)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,12 +54,15 @@ import com.github.damontecres.wholphin.services.ThemeSongPlayer
|
|||
import com.github.damontecres.wholphin.services.UserPreferencesService
|
||||
import com.github.damontecres.wholphin.services.deleteItem
|
||||
import com.github.damontecres.wholphin.ui.SlimItemFields
|
||||
import com.github.damontecres.wholphin.ui.cards.GridCard
|
||||
import com.github.damontecres.wholphin.ui.data.SortAndDirection
|
||||
import com.github.damontecres.wholphin.ui.detail.GridItemDetails
|
||||
import com.github.damontecres.wholphin.ui.detail.music.addToQueue
|
||||
import com.github.damontecres.wholphin.ui.equalsNotNull
|
||||
import com.github.damontecres.wholphin.ui.launchDefault
|
||||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import com.github.damontecres.wholphin.ui.playback.scale
|
||||
import com.github.damontecres.wholphin.ui.rememberInt
|
||||
import com.github.damontecres.wholphin.ui.showToast
|
||||
import com.github.damontecres.wholphin.ui.toServerString
|
||||
|
|
@ -843,6 +846,33 @@ fun CollectionFolderViewContent(
|
|||
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
||||
filterOptions: List<ItemFilterBy<*>> = DefaultFilterOptions,
|
||||
focusRequesterOnEmpty: FocusRequester? = null,
|
||||
gridCardContent: @Composable CollectionFolderViewScope.(
|
||||
GridItemDetails<BaseItem>,
|
||||
) -> Unit = { (item, index, onClick, onLongClick, widthPx, mod) ->
|
||||
GridCard(
|
||||
item = item,
|
||||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
imageContentScale = viewOptions.contentScale.scale,
|
||||
imageAspectRatio = viewOptions.aspectRatio.ratio,
|
||||
imageType = viewOptions.imageType,
|
||||
showTitle = viewOptions.showTitles,
|
||||
fillWidth = widthPx,
|
||||
modifier = mod,
|
||||
)
|
||||
},
|
||||
listItemContent: @Composable CollectionFolderViewScope.(
|
||||
GridItemDetails<BaseItem>,
|
||||
) -> Unit = { (item, index, onClick, onLongClick, _, mod) ->
|
||||
CollectionFolderListItem(
|
||||
item = item,
|
||||
dense = viewOptions.type == ViewOptionsType.DENSE_LIST,
|
||||
collectionType = collectionType,
|
||||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
modifier = mod,
|
||||
)
|
||||
},
|
||||
) {
|
||||
var position by rememberInt(savedPosition)
|
||||
|
||||
|
|
@ -1005,11 +1035,22 @@ fun CollectionFolderViewContent(
|
|||
focusRequester?.tryRequestFocus()
|
||||
clickedRandom = false
|
||||
}
|
||||
val scope =
|
||||
object : CollectionFolderViewScope {
|
||||
override val viewOptions: ViewOptions
|
||||
get() = state.viewOptions
|
||||
override val collectionType: CollectionType?
|
||||
get() = item?.data?.collectionType
|
||||
override val sortAndDirection: SortAndDirection
|
||||
get() = state.sortAndDirection
|
||||
override val collectionSize: Int
|
||||
get() = pager.data.size
|
||||
}
|
||||
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
if (state.viewOptions.type == ViewOptionsType.GRID) {
|
||||
CollectionFolderGrid(
|
||||
scope.CollectionFolderGrid(
|
||||
preferences = preferences,
|
||||
collectionType = item?.data?.collectionType,
|
||||
initialPosition = savedPosition,
|
||||
items = pager.data,
|
||||
sortAndDirection = state.sortAndDirection,
|
||||
|
|
@ -1023,12 +1064,12 @@ fun CollectionFolderViewContent(
|
|||
positionCallback?.invoke(columns, pos)
|
||||
},
|
||||
letterPosition = { viewActions.positionOfLetter(it) ?: -1 },
|
||||
viewOptions = state.viewOptions,
|
||||
onClickPlay = gridActions.onClickPlayRemoteButton!!,
|
||||
focusedItem = focusedItem,
|
||||
cardContent = gridCardContent,
|
||||
)
|
||||
} else {
|
||||
CollectionFolderList(
|
||||
scope.CollectionFolderList(
|
||||
preferences = preferences,
|
||||
collectionType = item?.data?.collectionType,
|
||||
initialPosition = savedPosition,
|
||||
|
|
@ -1044,9 +1085,9 @@ fun CollectionFolderViewContent(
|
|||
positionCallback?.invoke(columns, pos)
|
||||
},
|
||||
letterPosition = { viewActions.positionOfLetter(it) ?: -1 },
|
||||
viewOptions = state.viewOptions,
|
||||
onClickPlay = gridActions.onClickPlayRemoteButton!!,
|
||||
focusedItem = focusedItem,
|
||||
itemContent = listItemContent,
|
||||
)
|
||||
}
|
||||
androidx.compose.animation.AnimatedVisibility(
|
||||
|
|
@ -1085,3 +1126,13 @@ fun CollectionFolderViewContent(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope with global data for [CollectionFolderView], [CollectionFolderGrid], [CollectionFolderList], and individual items
|
||||
*/
|
||||
interface CollectionFolderViewScope {
|
||||
val viewOptions: ViewOptions
|
||||
val collectionType: CollectionType?
|
||||
val sortAndDirection: SortAndDirection
|
||||
val collectionSize: Int
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue