Add haptic feedback for drag and drop in Downloads
This commit is contained in:
1 parent
5dad21f4ea
commit
86a49f764e
4 files changed
+72
-62
No files matched your search
@@ -9,7 +9,6 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Pause
|
||||
import androidx.compose.material.icons.filled.PlayArrow
|
||||
import androidx.compose.material.icons.filled.Reorder
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
@@ -49,6 +48,7 @@ import com.hippo.ehviewer.download.downloadDir
|
||||
import com.hippo.ehviewer.ktbuilder.imageRequest
|
||||
import com.hippo.ehviewer.ui.tools.CropDefaults
|
||||
import com.hippo.ehviewer.ui.tools.CrystalCard
|
||||
import com.hippo.ehviewer.ui.tools.DragHandle
|
||||
import com.hippo.ehviewer.ui.tools.GalleryListCardRating
|
||||
import com.hippo.ehviewer.util.FileUtils
|
||||
import com.hippo.ehviewer.util.sendTo
|
||||
@@ -242,15 +242,7 @@ fun ReorderableItemScope.DownloadCard(
|
||||
bottom.linkTo(parent.bottom)
|
||||
},
|
||||
) {
|
||||
IconButton(
|
||||
onClick = { },
|
||||
modifier = Modifier.draggableHandle(),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Reorder,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
DragHandle()
|
||||
if (downloadState == DownloadInfo.STATE_WAIT || downloadState == DownloadInfo.STATE_DOWNLOAD) {
|
||||
IconButton(onClick = onStop) {
|
||||
Icon(imageVector = Icons.Default.Pause, contentDescription = null)
|
||||
|
||||
@@ -37,7 +37,6 @@ import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.filled.Pause
|
||||
import androidx.compose.material.icons.filled.PlayArrow
|
||||
import androidx.compose.material.icons.filled.Reorder
|
||||
import androidx.compose.material3.DismissDirection
|
||||
import androidx.compose.material3.DismissValue
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
@@ -66,6 +65,7 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringArrayResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -89,9 +89,11 @@ import com.hippo.ehviewer.ui.main.FabLayout
|
||||
import com.hippo.ehviewer.ui.navToReader
|
||||
import com.hippo.ehviewer.ui.showMoveDownloadLabelList
|
||||
import com.hippo.ehviewer.ui.tools.Deferred
|
||||
import com.hippo.ehviewer.ui.tools.DragHandle
|
||||
import com.hippo.ehviewer.ui.tools.FastScrollLazyColumn
|
||||
import com.hippo.ehviewer.ui.tools.LocalDialogState
|
||||
import com.hippo.ehviewer.ui.tools.SwipeToDismissBox2
|
||||
import com.hippo.ehviewer.ui.tools.draggingHapticFeedback
|
||||
import com.hippo.ehviewer.util.containsIgnoreCase
|
||||
import com.hippo.ehviewer.util.findActivity
|
||||
import com.hippo.ehviewer.util.mapToLongArray
|
||||
@@ -123,6 +125,7 @@ fun DownloadsScreen(navigator: NavController) {
|
||||
val activity = remember(context) { context.findActivity<MainActivity>() }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val dialogState = LocalDialogState.current
|
||||
val view = LocalView.current
|
||||
val title = stringResource(R.string.scene_download_title, label ?: stringResource(R.string.download_all))
|
||||
val hint = stringResource(R.string.search_bar_hint, title)
|
||||
val defaultName = stringResource(R.string.default_download_label_name)
|
||||
@@ -208,6 +211,7 @@ fun DownloadsScreen(navigator: NavController) {
|
||||
coroutineScope.launch {
|
||||
DownloadManager.moveLabel(from.index - 2, to.index - 2)
|
||||
}
|
||||
view.performHapticFeedback(draggingHapticFeedback)
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
@@ -299,12 +303,7 @@ fun DownloadsScreen(navigator: NavController) {
|
||||
) {
|
||||
Icon(imageVector = Icons.Default.Edit, contentDescription = null)
|
||||
}
|
||||
IconButton(
|
||||
onClick = {},
|
||||
modifier = Modifier.draggableHandle(),
|
||||
) {
|
||||
Icon(imageVector = Icons.Default.Reorder, contentDescription = null)
|
||||
}
|
||||
DragHandle()
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -412,6 +411,7 @@ fun DownloadsScreen(navigator: NavController) {
|
||||
coroutineScope.launchIO {
|
||||
EhDB.updateDownloadInfo(newList)
|
||||
}
|
||||
view.performHapticFeedback(draggingHapticFeedback)
|
||||
}
|
||||
FastScrollLazyColumn(
|
||||
modifier = Modifier.nestedScroll(searchBarConnection),
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.hippo.ehviewer.ui.scene
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewConfiguration
|
||||
@@ -43,7 +42,6 @@ import androidx.compose.material.icons.automirrored.filled.LastPage
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ImageSearch
|
||||
import androidx.compose.material.icons.filled.Refresh
|
||||
import androidx.compose.material.icons.filled.Reorder
|
||||
import androidx.compose.material.icons.filled.Translate
|
||||
import androidx.compose.material.icons.outlined.Bookmarks
|
||||
import androidx.compose.material3.DismissDirection
|
||||
@@ -148,17 +146,16 @@ import com.hippo.ehviewer.ui.main.NormalSearch
|
||||
import com.hippo.ehviewer.ui.main.SearchAdvanced
|
||||
import com.hippo.ehviewer.ui.scene.GalleryListFragment.Companion.toStartArgs
|
||||
import com.hippo.ehviewer.ui.tools.Deferred
|
||||
import com.hippo.ehviewer.ui.tools.DragHandle
|
||||
import com.hippo.ehviewer.ui.tools.LocalDialogState
|
||||
import com.hippo.ehviewer.ui.tools.SwipeToDismissBox2
|
||||
import com.hippo.ehviewer.ui.tools.animateFloatMergePredictiveBackAsState
|
||||
import com.hippo.ehviewer.ui.tools.draggingHapticFeedback
|
||||
import com.hippo.ehviewer.ui.tools.observed
|
||||
import com.hippo.ehviewer.ui.tools.rememberInVM
|
||||
import com.hippo.ehviewer.util.AppConfig
|
||||
import com.hippo.ehviewer.util.findActivity
|
||||
import com.hippo.ehviewer.util.getParcelableCompat
|
||||
import com.hippo.ehviewer.util.isAtLeastOMR1
|
||||
import com.hippo.ehviewer.util.isAtLeastR
|
||||
import com.hippo.ehviewer.util.isAtLeastU
|
||||
import com.hippo.ehviewer.util.pickVisualMedia
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
@@ -416,14 +413,7 @@ fun GalleryListScreen(lub: ListUrlBuilder, navigator: NavController) {
|
||||
list.zip(range).forEach { it.first.position = it.second }
|
||||
EhDB.updateQuickSearch(list)
|
||||
}
|
||||
val feedbackConstant = if (isAtLeastU) {
|
||||
HapticFeedbackConstants.SEGMENT_FREQUENT_TICK
|
||||
} else if (isAtLeastOMR1) {
|
||||
HapticFeedbackConstants.TEXT_HANDLE_MOVE
|
||||
} else {
|
||||
HapticFeedbackConstants.CLOCK_TICK
|
||||
}
|
||||
view.performHapticFeedback(feedbackConstant)
|
||||
view.performHapticFeedback(draggingHapticFeedback)
|
||||
}
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
@@ -477,38 +467,7 @@ fun GalleryListScreen(lub: ListUrlBuilder, navigator: NavController) {
|
||||
Text(text = item.name)
|
||||
},
|
||||
trailingContent = {
|
||||
IconButton(
|
||||
onClick = {},
|
||||
modifier = Modifier.draggableHandle(
|
||||
onDragStarted = {
|
||||
val feedbackConstant = if (isAtLeastU) {
|
||||
HapticFeedbackConstants.DRAG_START
|
||||
} else if (isAtLeastR) {
|
||||
HapticFeedbackConstants.GESTURE_START
|
||||
} else if (isAtLeastOMR1) {
|
||||
HapticFeedbackConstants.KEYBOARD_PRESS
|
||||
} else {
|
||||
HapticFeedbackConstants.VIRTUAL_KEY
|
||||
}
|
||||
view.performHapticFeedback(feedbackConstant)
|
||||
},
|
||||
onDragStopped = {
|
||||
val feedbackConstant = if (isAtLeastR) {
|
||||
HapticFeedbackConstants.GESTURE_END
|
||||
} else if (isAtLeastOMR1) {
|
||||
HapticFeedbackConstants.KEYBOARD_RELEASE
|
||||
} else {
|
||||
HapticFeedbackConstants.VIRTUAL_KEY_RELEASE
|
||||
}
|
||||
view.performHapticFeedback(feedbackConstant)
|
||||
},
|
||||
),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Reorder,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
DragHandle()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.hippo.ehviewer.ui.tools
|
||||
|
||||
import android.view.HapticFeedbackConstants
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Reorder
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import com.hippo.ehviewer.util.isAtLeastOMR1
|
||||
import com.hippo.ehviewer.util.isAtLeastR
|
||||
import com.hippo.ehviewer.util.isAtLeastU
|
||||
import sh.calvin.reorderable.ReorderableItemScope
|
||||
|
||||
@Composable
|
||||
fun ReorderableItemScope.DragHandle(modifier: Modifier = Modifier) {
|
||||
val view = LocalView.current
|
||||
IconButton(
|
||||
onClick = {},
|
||||
modifier = modifier.draggableHandle(
|
||||
onDragStarted = {
|
||||
val feedbackConstant = if (isAtLeastU) {
|
||||
HapticFeedbackConstants.DRAG_START
|
||||
} else if (isAtLeastR) {
|
||||
HapticFeedbackConstants.GESTURE_START
|
||||
} else if (isAtLeastOMR1) {
|
||||
HapticFeedbackConstants.KEYBOARD_PRESS
|
||||
} else {
|
||||
HapticFeedbackConstants.VIRTUAL_KEY
|
||||
}
|
||||
view.performHapticFeedback(feedbackConstant)
|
||||
},
|
||||
onDragStopped = {
|
||||
val feedbackConstant = if (isAtLeastR) {
|
||||
HapticFeedbackConstants.GESTURE_END
|
||||
} else if (isAtLeastOMR1) {
|
||||
HapticFeedbackConstants.KEYBOARD_RELEASE
|
||||
} else {
|
||||
HapticFeedbackConstants.VIRTUAL_KEY_RELEASE
|
||||
}
|
||||
view.performHapticFeedback(feedbackConstant)
|
||||
},
|
||||
),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Reorder,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val draggingHapticFeedback = if (isAtLeastU) {
|
||||
HapticFeedbackConstants.SEGMENT_FREQUENT_TICK
|
||||
} else if (isAtLeastOMR1) {
|
||||
HapticFeedbackConstants.TEXT_HANDLE_MOVE
|
||||
} else {
|
||||
HapticFeedbackConstants.CLOCK_TICK
|
||||
}
|
||||
Reference in new issue
Block a user