[WIP] Pageturn

This commit is contained in:
tom5079
2021-12-18 13:32:07 +09:00
parent adf18341d0
commit a57b1d5614
3 changed files with 87 additions and 40 deletions

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="ce021712e3b19b2b04" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2021-12-17T11:08:36.835795Z" />
</component>
</project>

View File

@@ -44,11 +44,13 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.input.pointer.*
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastFirstOrNull
import com.google.accompanist.drawablepainter.rememberDrawablePainter
import kotlinx.coroutines.*
import org.kodein.di.DIAware
@@ -58,14 +60,10 @@ import org.kodein.log.newLogger
import xyz.quaver.pupil.*
import xyz.quaver.pupil.R
import xyz.quaver.pupil.sources.SearchResultEvent
import xyz.quaver.pupil.ui.composable.FloatingActionButtonState
import xyz.quaver.pupil.ui.composable.FloatingSearchBar
import xyz.quaver.pupil.ui.composable.MultipleFloatingActionButton
import xyz.quaver.pupil.ui.composable.SubFabItem
import xyz.quaver.pupil.ui.composable.*
import xyz.quaver.pupil.ui.dialog.OpenWithItemIDDialog
import xyz.quaver.pupil.ui.dialog.SourceSelectDialog
import xyz.quaver.pupil.ui.theme.PupilTheme
import xyz.quaver.pupil.ui.composable.ProgressCard
import xyz.quaver.pupil.ui.dialog.OpenWithItemIDDialog
import xyz.quaver.pupil.ui.viewmodel.MainViewModel
import xyz.quaver.pupil.util.*
import kotlin.math.*
@@ -90,6 +88,20 @@ class MainActivity : ComponentActivity(), DIAware {
PupilTheme {
val focusManager = LocalFocusManager.current
val maxPage by model.maxPage.collectAsState(0)
val pageTurnIndicatorHeight = LocalDensity.current.run { 64.dp.toPx() }
val prevPageAvailable by derivedStateOf {
model.currentPage > 1
}
val nextPageAvailable by derivedStateOf {
model.currentPage <= maxPage
}
var overscroll: Float? by remember { mutableStateOf(null) }
var isFabExpanded by remember { mutableStateOf(FloatingActionButtonState.COLLAPSED) }
var isFabVisible by remember { mutableStateOf(true) }
@@ -185,24 +197,40 @@ class MainActivity : ComponentActivity(), DIAware {
}
) {
Box(Modifier.fillMaxSize()) {
LazyColumn(
Modifier
.fillMaxSize()
.offset(0.dp, overscroll?.let { overscroll -> LocalDensity.current.run { overscroll.toDp() } } ?: 0.dp)
.nestedScroll(object : NestedScrollConnection {
override fun onPreScroll(
available: Offset,
source: NestedScrollSource
): Offset {
searchBarOffset =
(searchBarOffset + available.y.roundToInt()).coerceIn(
-searchBarHeight,
0
)
val overscrollSnapshot = overscroll
isFabVisible = available.y > 0f
if (overscrollSnapshot == null || overscrollSnapshot == 0f) {
searchBarOffset =
(searchBarOffset + available.y.roundToInt()).coerceIn(
-searchBarHeight,
0
)
return Offset.Zero
isFabVisible = available.y > 0f
return Offset.Zero
} else {
val newOverscroll =
if (overscrollSnapshot > 0f && available.y < 0f)
max(overscrollSnapshot + available.y, 0f)
else if (overscrollSnapshot < 0f && available.y > 0f)
min(overscrollSnapshot + available.y, 0f)
else
overscrollSnapshot
return Offset(0f, newOverscroll - overscrollSnapshot).also {
overscroll = newOverscroll
}
}
}
override fun onPostScroll(
@@ -210,11 +238,41 @@ class MainActivity : ComponentActivity(), DIAware {
available: Offset,
source: NestedScrollSource
): Offset {
if (available.y == 0f || source == NestedScrollSource.Fling) return Offset.Zero
return overscroll?.let {
val newOverscroll = (it + available.y).coerceIn(-pageTurnIndicatorHeight, pageTurnIndicatorHeight)
return super.onPostScroll(consumed, available, source)
Offset(0f, newOverscroll - it).also {
overscroll = newOverscroll
}
} ?: Offset.Zero
}
}),
}).pointerInput(Unit) {
forEachGesture {
awaitPointerEventScope {
val down = awaitFirstDown(requireUnconsumed = false)
var pointer = down.id
overscroll = 0f
while (true) {
val event = awaitPointerEvent()
val dragEvent = event.changes.fastFirstOrNull { it.id == pointer }!!
if (dragEvent.changedToUpIgnoreConsumed()) {
val otherDown = event.changes.fastFirstOrNull { it.pressed }
if (otherDown == null) {
dragEvent.consumePositionChange()
overscroll = null
break
}
else
pointer = otherDown.id
}
}
}
}
},
contentPadding = PaddingValues(0.dp, 56.dp, 0.dp, 0.dp)
) {
items(model.searchResults, key = { it.itemID }) { itemInfo ->
@@ -251,9 +309,11 @@ class MainActivity : ComponentActivity(), DIAware {
Image(
painterResource(model.source.iconResID),
contentDescription = null,
modifier = Modifier.size(24.dp).clickable {
sourceSelectDialog = true
}
modifier = Modifier
.size(24.dp)
.clickable {
sourceSelectDialog = true
}
)
Icon(
Icons.Default.Sort,

View File

@@ -19,10 +19,7 @@
package xyz.quaver.pupil.ui.viewmodel
import android.app.Application
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.*
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
@@ -40,6 +37,7 @@ import xyz.quaver.pupil.sources.History
import xyz.quaver.pupil.sources.ItemInfo
import xyz.quaver.pupil.sources.Source
import xyz.quaver.pupil.util.source
import kotlin.math.ceil
import kotlin.random.Random
@Suppress("UNCHECKED_CAST")
@@ -78,6 +76,12 @@ class MainViewModel(app: Application) : AndroidViewModel(app), DIAware {
var totalItems by mutableStateOf(0)
private set
val maxPage by derivedStateOf {
resultsPerPage.map {
ceil(totalItems / it.toDouble()).toInt()
}
}
fun setSourceAndReset(sourceName: String) {
source = sourceFactory(sourceName)
sortModeIndex = 0