From b1ef7850b7fb8e723a6cf068879570c113f663d4 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Sat, 20 Jan 2024 04:27:00 +0300 Subject: [PATCH 01/19] SwipeToAction composable --- app/src/main/java/com/jerboa/Utils.kt | 45 +++++ .../ui/components/common/SwipeToAction.kt | 170 ++++++++++++++++++ .../main/java/com/jerboa/ui/theme/Color.kt | 12 ++ .../com/jerboa/ui/theme/JerboaColorScheme.kt | 4 + 4 files changed, 231 insertions(+) create mode 100644 app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt diff --git a/app/src/main/java/com/jerboa/Utils.kt b/app/src/main/java/com/jerboa/Utils.kt index 4478d4339..cfec577bd 100644 --- a/app/src/main/java/com/jerboa/Utils.kt +++ b/app/src/main/java/com/jerboa/Utils.kt @@ -27,9 +27,14 @@ import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatDelegate import androidx.browser.customtabs.CustomTabsIntent import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Bookmark +import androidx.compose.material.icons.outlined.Comment import androidx.compose.material3.DrawerState +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHostState +import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.snapshots.SnapshotStateList @@ -38,6 +43,8 @@ import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp @@ -55,6 +62,7 @@ import com.jerboa.db.APP_SETTINGS_DEFAULT import com.jerboa.db.entity.AppSettings import com.jerboa.ui.components.common.Route import com.jerboa.ui.theme.SMALL_PADDING +import com.jerboa.ui.theme.jerboaColorScheme import it.vercruysse.lemmyapi.v0x19.datatypes.* import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList @@ -954,6 +962,43 @@ enum class PostType { } } +enum class SwipeActionType() { + Upvote, + Downvote, + Reply, + Save, + ; + + companion object { + fun getActionToRangeList(actions: List): List, SwipeActionType>> { + return actions.mapIndexed { index, it -> + (0.1f + 0.12f * index) + .rangeUntil(if (index == actions.size - 1) 1f else (0.1f + 0.12f * (index + 1))) to it + } + } + } + + @Composable + fun getImageVector(): ImageVector { + return when (this) { + Upvote -> ImageVector.vectorResource(id = R.drawable.up_outline) + Downvote -> ImageVector.vectorResource(id = R.drawable.down_outline) + Reply -> Icons.Outlined.Comment + Save -> Icons.Outlined.Bookmark + } + } + + @Composable + fun getActionColor(): Color { + return when (this) { + Upvote -> MaterialTheme.jerboaColorScheme.upvoteSwipe + Downvote -> MaterialTheme.jerboaColorScheme.downvoteSwipe + Reply -> MaterialTheme.jerboaColorScheme.replySwipe + Save -> MaterialTheme.jerboaColorScheme.saveSwipe + } + } +} + fun isSameInstance( url: String, instance: String, diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt new file mode 100644 index 000000000..7f5474998 --- /dev/null +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -0,0 +1,170 @@ +package com.jerboa.ui.components.common + +import androidx.compose.animation.animateColor +import androidx.compose.animation.core.spring +import androidx.compose.animation.core.updateTransition +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.requiredWidth +import androidx.compose.material3.DismissDirection +import androidx.compose.material3.DismissState +import androidx.compose.material3.DismissValue +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.SwipeToDismiss +import androidx.compose.material3.rememberDismissState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalHapticFeedback +import androidx.compose.ui.unit.dp +import com.jerboa.SwipeActionType + +@Composable +@ExperimentalMaterial3Api +fun SwipeToAction( + leftActions: List, + rightActions: List, + swipeableContent: @Composable RowScope.() -> Unit, + swipeState: DismissState, +) { + val haptic = LocalHapticFeedback.current + + val leftActionsRanges = + remember(leftActions) { SwipeActionType.getActionToRangeList(leftActions) } + val rightActionsRanges = + remember(rightActions) { SwipeActionType.getActionToRangeList(rightActions) } + + fun actionByState(state: DismissState): Pair, SwipeActionType>? { + return when (state.currentValue) { + DismissValue.DismissedToEnd -> { + leftActionsRanges.findLast { swipeState.progress in it.first } + } + + DismissValue.DismissedToStart -> { + rightActionsRanges.findLast { swipeState.progress in it.first } + } + + else -> null + } + } + + val swipeAction = remember(swipeState) { actionByState(swipeState) } + + SwipeToDismiss( + directions = + remember(leftActions, rightActions) { + setOfNotNull( + if (leftActions.isNotEmpty()) DismissDirection.StartToEnd else null, + if (rightActions.isNotEmpty()) DismissDirection.EndToStart else null, + ) + }, + state = swipeState, + background = { + val lastSwipeAction = remember { mutableStateOf(null) } + val transition = updateTransition(swipeState, label = "swipe state") + val color by transition.animateColor( + transitionSpec = { + val currentAction = remember(swipeState) { actionByState(swipeState) } + // vibrates when icon changes + if (lastSwipeAction.value != currentAction?.second) { + haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) + lastSwipeAction.value = currentAction?.second + } + spring(stiffness = 50f) + }, + label = "swipe color animation", + targetValueByState = { state -> + val currentAction = remember(state) { actionByState(swipeState) } + currentAction?.second?.getActionColor() ?: Color.Transparent + }, + ) + Box( + modifier = + Modifier + .fillMaxSize(), + ) { + Box( + modifier = + Modifier + .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) + .fillMaxHeight() + .background(color = color) + .align(if (swipeState.currentValue == DismissValue.DismissedToStart) Alignment.TopEnd else Alignment.TopStart), + contentAlignment = Alignment.CenterStart, + ) { + val tint = Color.White + val modifier = + Modifier + .padding(10.dp) + .requiredWidth(35.dp) + .fillMaxHeight() + + swipeAction?.second?.getImageVector()?.let { icon -> + Icon( + imageVector = icon, + contentDescription = null, + tint = tint, + modifier = modifier, + ) + } + } + } + }, + dismissContent = { swipeableContent() }, + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun rememberSwipeActionState( + leftActions: List, + rightActions: List, + onAction: (action: SwipeActionType) -> Unit, +): DismissState { + /* + This hacky solution is required because confirmValueChange lambda doesn't pass progress state + */ + val leftActionsRanges = + remember(leftActions) { SwipeActionType.getActionToRangeList(leftActions) } + val rightActionsRanges = + remember(rightActions) { SwipeActionType.getActionToRangeList(rightActions) } + val progressState = remember { mutableFloatStateOf(1.0f) } + val dismissState = + rememberDismissState( + positionalThreshold = { 0f }, + confirmValueChange = { dismissValue -> + val action = + when (dismissValue) { + DismissValue.DismissedToEnd -> { + leftActionsRanges.findLast { progressState.floatValue in it.first } + } + + DismissValue.DismissedToStart -> { + rightActionsRanges.findLast { progressState.floatValue in it.first } + } + + else -> { + null + } + } + action?.second?.let { actionType -> + onAction(actionType) + } + false // do not dismiss + }, + ) + progressState.floatValue = dismissState.progress + return dismissState +} diff --git a/app/src/main/java/com/jerboa/ui/theme/Color.kt b/app/src/main/java/com/jerboa/ui/theme/Color.kt index c9cb47dc0..1b47e9488 100644 --- a/app/src/main/java/com/jerboa/ui/theme/Color.kt +++ b/app/src/main/java/com/jerboa/ui/theme/Color.kt @@ -373,6 +373,10 @@ fun crimson(): Pair { val md_theme_dark_scrim = Color(0xFF000000) val jerboa_image_highlight = Color(0xCCD1D1D1) val jerboa_video_highlight = Color(0xCCC20000) + val jerboa_upvote_swipe = Color(0xff4caf50) + val jerboa_downvote_swipe = Color(0xfff44336) + val jerboa_save_swipe = Color(0xff448aff) + val jerboa_reply_swipe = Color(0xffffa000) // val seed = Color(0xFF78B0FF) @@ -447,6 +451,10 @@ fun crimson(): Pair { material = light, imageHighlight = jerboa_image_highlight, videoHighlight = jerboa_video_highlight, + upvoteSwipe = jerboa_upvote_swipe, + downvoteSwipe = jerboa_downvote_swipe, + saveSwipe = jerboa_save_swipe, + replySwipe = jerboa_reply_swipe, ) val jerboaDark = @@ -454,6 +462,10 @@ fun crimson(): Pair { material = dark, imageHighlight = jerboa_image_highlight, videoHighlight = jerboa_video_highlight, + upvoteSwipe = jerboa_upvote_swipe, + downvoteSwipe = jerboa_downvote_swipe, + saveSwipe = jerboa_save_swipe, + replySwipe = jerboa_reply_swipe, ) return Pair(jerboaLight, jerboaDark) diff --git a/app/src/main/java/com/jerboa/ui/theme/JerboaColorScheme.kt b/app/src/main/java/com/jerboa/ui/theme/JerboaColorScheme.kt index 22de8e77d..527d2b39d 100644 --- a/app/src/main/java/com/jerboa/ui/theme/JerboaColorScheme.kt +++ b/app/src/main/java/com/jerboa/ui/theme/JerboaColorScheme.kt @@ -11,4 +11,8 @@ data class JerboaColorScheme( val material: ColorScheme = darkColorScheme(), // the default Material color scheme val imageHighlight: Color = Color(0xCCD1D1D1), // the color that highlights an image thumb val videoHighlight: Color = Color(0xCCC20000), // the color that highlights a video thumb + val upvoteSwipe: Color = Color(0xff4caf50), // the background color for upvote when swiping + val downvoteSwipe: Color = Color(0xfff44336), // the background color for downvote when swiping + val saveSwipe: Color = Color(0xff448aff), // the background color for share when swiping + val replySwipe: Color = Color(0xffffa000), // the background color for reply when swiping ) From 109337d7902e5bf23ca87d8544f414a036bf592e Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 23 Jan 2024 00:22:53 +0300 Subject: [PATCH 02/19] Swipe to downvote/upvote feature implemented with preset-based customization --- app/schemas/com.jerboa.db.AppDB/27.json | 260 +++++++++++++++++ app/src/main/java/com/jerboa/MainActivity.kt | 6 + app/src/main/java/com/jerboa/Utils.kt | 45 --- app/src/main/java/com/jerboa/db/AppDB.kt | 3 +- .../java/com/jerboa/db/AppDBMigrations.kt | 21 ++ .../java/com/jerboa/db/entity/AppSettings.kt | 5 + .../java/com/jerboa/feat/SwipeToActionType.kt | 95 +++++++ .../ui/components/comment/CommentNode.kt | 265 +++++++++++------- .../ui/components/comment/CommentNodes.kt | 5 + .../ui/components/common/SwipeToAction.kt | 63 +++-- .../components/community/CommunityActivity.kt | 2 + .../ui/components/home/BottomNavActivity.kt | 3 + .../jerboa/ui/components/home/HomeActivity.kt | 4 + .../person/PersonProfileActivity.kt | 5 + .../jerboa/ui/components/post/PostActivity.kt | 26 ++ .../jerboa/ui/components/post/PostListing.kt | 249 ++++++++-------- .../jerboa/ui/components/post/PostListings.kt | 164 ++++++++--- .../lookandfeel/LookAndFeelActivity.kt | 22 +- .../main/java/com/jerboa/ui/theme/Color.kt | 14 +- .../com/jerboa/ui/theme/JerboaColorScheme.kt | 4 - app/src/main/res/values-ru/strings.xml | 29 +- app/src/main/res/values/strings.xml | 6 + 22 files changed, 920 insertions(+), 376 deletions(-) create mode 100644 app/schemas/com.jerboa.db.AppDB/27.json create mode 100644 app/src/main/java/com/jerboa/feat/SwipeToActionType.kt diff --git a/app/schemas/com.jerboa.db.AppDB/27.json b/app/schemas/com.jerboa.db.AppDB/27.json new file mode 100644 index 000000000..96d84f5b7 --- /dev/null +++ b/app/schemas/com.jerboa.db.AppDB/27.json @@ -0,0 +1,260 @@ +{ + "formatVersion": 1, + "database": { + "version": 27, + "identityHash": "8e8aa32b002a7ce0d76dfb82e9309bd0", + "entities": [ + { + "tableName": "Account", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `current` INTEGER NOT NULL, `instance` TEXT NOT NULL, `name` TEXT NOT NULL, `jwt` TEXT NOT NULL, `default_listing_type` INTEGER NOT NULL DEFAULT 0, `default_sort_type` INTEGER NOT NULL DEFAULT 0, `verification_state` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "current", + "columnName": "current", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "instance", + "columnName": "instance", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "jwt", + "columnName": "jwt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "defaultListingType", + "columnName": "default_listing_type", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "defaultSortType", + "columnName": "default_sort_type", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "verificationState", + "columnName": "verification_state", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AppSettings", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `font_size` INTEGER NOT NULL DEFAULT 16, `theme` INTEGER NOT NULL DEFAULT 0, `theme_color` INTEGER NOT NULL DEFAULT 0, `viewed_changelog` INTEGER NOT NULL DEFAULT 0, `post_view_mode` INTEGER NOT NULL DEFAULT 0, `show_bottom_nav` INTEGER NOT NULL DEFAULT 1, `post_navigation_gesture_mode` INTEGER NOT NULL DEFAULT 0, `show_collapsed_comment_content` INTEGER NOT NULL DEFAULT 0, `show_comment_action_bar_by_default` INTEGER NOT NULL DEFAULT 1, `show_voting_arrows_in_list_view` INTEGER NOT NULL DEFAULT 1, `show_parent_comment_navigation_buttons` INTEGER NOT NULL DEFAULT 0, `navigate_parent_comments_with_volume_buttons` INTEGER NOT NULL DEFAULT 0, `use_custom_tabs` INTEGER NOT NULL DEFAULT 1, `use_private_tabs` INTEGER NOT NULL DEFAULT 0, `secure_window` INTEGER NOT NULL DEFAULT 0, `blur_nsfw` INTEGER NOT NULL DEFAULT 1, `show_text_descriptions_in_navbar` INTEGER NOT NULL DEFAULT 1, `markAsReadOnScroll` INTEGER NOT NULL DEFAULT 0, `backConfirmationMode` INTEGER NOT NULL DEFAULT 1, `show_post_link_previews` INTEGER NOT NULL DEFAULT 1, `post_actionbar_mode` INTEGER NOT NULL DEFAULT 0, `auto_play_gifs` INTEGER NOT NULL DEFAULT 0, `swipe_to_action_preset` INTEGER NOT NULL DEFAULT 1)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "fontSize", + "columnName": "font_size", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "16" + }, + { + "fieldPath": "theme", + "columnName": "theme", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "themeColor", + "columnName": "theme_color", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "viewedChangelog", + "columnName": "viewed_changelog", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "postViewMode", + "columnName": "post_view_mode", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "showBottomNav", + "columnName": "show_bottom_nav", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "postNavigationGestureMode", + "columnName": "post_navigation_gesture_mode", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "showCollapsedCommentContent", + "columnName": "show_collapsed_comment_content", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "showCommentActionBarByDefault", + "columnName": "show_comment_action_bar_by_default", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "showVotingArrowsInListView", + "columnName": "show_voting_arrows_in_list_view", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "showParentCommentNavigationButtons", + "columnName": "show_parent_comment_navigation_buttons", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "navigateParentCommentsWithVolumeButtons", + "columnName": "navigate_parent_comments_with_volume_buttons", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "useCustomTabs", + "columnName": "use_custom_tabs", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "usePrivateTabs", + "columnName": "use_private_tabs", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "secureWindow", + "columnName": "secure_window", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "blurNSFW", + "columnName": "blur_nsfw", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "showTextDescriptionsInNavbar", + "columnName": "show_text_descriptions_in_navbar", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "markAsReadOnScroll", + "columnName": "markAsReadOnScroll", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "backConfirmationMode", + "columnName": "backConfirmationMode", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "showPostLinkPreviews", + "columnName": "show_post_link_previews", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "postActionbarMode", + "columnName": "post_actionbar_mode", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "autoPlayGifs", + "columnName": "auto_play_gifs", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "swipeToActionPreset", + "columnName": "swipe_to_action_preset", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8e8aa32b002a7ce0d76dfb82e9309bd0')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/com/jerboa/MainActivity.kt b/app/src/main/java/com/jerboa/MainActivity.kt index b8acf24af..b5725252c 100644 --- a/app/src/main/java/com/jerboa/MainActivity.kt +++ b/app/src/main/java/com/jerboa/MainActivity.kt @@ -233,6 +233,7 @@ class MainActivity : AppCompatActivity() { showPostLinkPreviews = appSettings.showPostLinkPreviews, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset ) } @@ -276,6 +277,7 @@ class MainActivity : AppCompatActivity() { showPostLinkPreviews = appSettings.showPostLinkPreviews, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset ) } @@ -316,6 +318,7 @@ class MainActivity : AppCompatActivity() { onBack = appState::popBackStack, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset ) } @@ -353,6 +356,7 @@ class MainActivity : AppCompatActivity() { drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset ) } @@ -464,6 +468,7 @@ class MainActivity : AppCompatActivity() { blurNSFW = appSettings.blurNSFW, showPostLinkPreview = appSettings.showPostLinkPreviews, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset ) } } @@ -497,6 +502,7 @@ class MainActivity : AppCompatActivity() { blurNSFW = appSettings.blurNSFW, showPostLinkPreview = appSettings.showPostLinkPreviews, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset ) } diff --git a/app/src/main/java/com/jerboa/Utils.kt b/app/src/main/java/com/jerboa/Utils.kt index 8b3b646c7..c8d5032d4 100644 --- a/app/src/main/java/com/jerboa/Utils.kt +++ b/app/src/main/java/com/jerboa/Utils.kt @@ -27,14 +27,9 @@ import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatDelegate import androidx.browser.customtabs.CustomTabsIntent import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.Bookmark -import androidx.compose.material.icons.outlined.Comment import androidx.compose.material3.DrawerState -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHostState -import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.snapshots.SnapshotStateList @@ -43,8 +38,6 @@ import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.drawscope.DrawScope -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp @@ -62,7 +55,6 @@ import com.jerboa.db.APP_SETTINGS_DEFAULT import com.jerboa.db.entity.AppSettings import com.jerboa.ui.components.common.Route import com.jerboa.ui.theme.SMALL_PADDING -import com.jerboa.ui.theme.jerboaColorScheme import it.vercruysse.lemmyapi.v0x19.datatypes.* import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList @@ -962,43 +954,6 @@ enum class PostType { } } -enum class SwipeActionType() { - Upvote, - Downvote, - Reply, - Save, - ; - - companion object { - fun getActionToRangeList(actions: List): List, SwipeActionType>> { - return actions.mapIndexed { index, it -> - (0.1f + 0.12f * index) - .rangeUntil(if (index == actions.size - 1) 1f else (0.1f + 0.12f * (index + 1))) to it - } - } - } - - @Composable - fun getImageVector(): ImageVector { - return when (this) { - Upvote -> ImageVector.vectorResource(id = R.drawable.up_outline) - Downvote -> ImageVector.vectorResource(id = R.drawable.down_outline) - Reply -> Icons.Outlined.Comment - Save -> Icons.Outlined.Bookmark - } - } - - @Composable - fun getActionColor(): Color { - return when (this) { - Upvote -> MaterialTheme.jerboaColorScheme.upvoteSwipe - Downvote -> MaterialTheme.jerboaColorScheme.downvoteSwipe - Reply -> MaterialTheme.jerboaColorScheme.replySwipe - Save -> MaterialTheme.jerboaColorScheme.saveSwipe - } - } -} - fun isSameInstance( url: String, instance: String, diff --git a/app/src/main/java/com/jerboa/db/AppDB.kt b/app/src/main/java/com/jerboa/db/AppDB.kt index 0f4f9d31b..811c48478 100644 --- a/app/src/main/java/com/jerboa/db/AppDB.kt +++ b/app/src/main/java/com/jerboa/db/AppDB.kt @@ -39,10 +39,11 @@ val APP_SETTINGS_DEFAULT = showPostLinkPreviews = true, postActionbarMode = 0, autoPlayGifs = false, + swipeToActionPreset = 1 ) @Database( - version = 26, + version = 27, entities = [Account::class, AppSettings::class], exportSchema = true, ) diff --git a/app/src/main/java/com/jerboa/db/AppDBMigrations.kt b/app/src/main/java/com/jerboa/db/AppDBMigrations.kt index 719bf964d..d9bd8f540 100644 --- a/app/src/main/java/com/jerboa/db/AppDBMigrations.kt +++ b/app/src/main/java/com/jerboa/db/AppDBMigrations.kt @@ -384,6 +384,25 @@ val MIGRATION_26_25 = } } +val MIGRATION_26_27 = + object : Migration(26, 27) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL(UPDATE_APP_CHANGELOG_UNVIEWED) + db.execSQL( + "ALTER TABLE AppSettings ADD COLUMN swipe_to_action_preset INTEGER NOT NULL DEFAULT 1", + ) + } + } + +val MIGRATION_27_26 = + object : Migration(27, 26) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL( + "ALTER TABLE AppSettings DROP COLUMN swipe_to_action_preset", + ) + } + } + // Don't forget to test your migration with `./gradlew app:connectAndroidTest` val MIGRATIONS_LIST = arrayOf( @@ -417,4 +436,6 @@ val MIGRATIONS_LIST = MIGRATION_25_24, MIGRATION_25_26, MIGRATION_26_25, + MIGRATION_26_27, + MIGRATION_27_26 ) diff --git a/app/src/main/java/com/jerboa/db/entity/AppSettings.kt b/app/src/main/java/com/jerboa/db/entity/AppSettings.kt index cf3dc3e98..b018b7084 100644 --- a/app/src/main/java/com/jerboa/db/entity/AppSettings.kt +++ b/app/src/main/java/com/jerboa/db/entity/AppSettings.kt @@ -118,4 +118,9 @@ data class AppSettings( defaultValue = "0", ) val autoPlayGifs: Boolean, + @ColumnInfo( + name = "swipe_to_action_preset", + defaultValue = "1", + ) + val swipeToActionPreset: Int, ) diff --git a/app/src/main/java/com/jerboa/feat/SwipeToActionType.kt b/app/src/main/java/com/jerboa/feat/SwipeToActionType.kt new file mode 100644 index 000000000..c4342adce --- /dev/null +++ b/app/src/main/java/com/jerboa/feat/SwipeToActionType.kt @@ -0,0 +1,95 @@ +package com.jerboa.feat + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Bookmark +import androidx.compose.material.icons.outlined.Comment +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.vectorResource +import com.jerboa.R + +enum class SwipeToActionType() { + Upvote, + Downvote, + Reply, + Save, + ; + + companion object { + fun getActionToRangeList(actions: List): List, SwipeToActionType>> { + val delta = if(actions.size > 2) 0.14f else 0.18f + return actions.mapIndexed { index, it -> + (0.1f + delta * index) + .rangeUntil(if (index == actions.size - 1) 1f else (0.1f + delta * (index + 1))) to it + } + } + + fun getDefaultLeftActions(): List { + return listOf(Reply, Save) + } + + fun getDefaultRightActions(): List { + return listOf(Upvote, Downvote) + } + } + + @Composable + fun getImageVector(): ImageVector { + return when (this) { + Upvote -> ImageVector.vectorResource(id = R.drawable.up_outline) + Downvote -> ImageVector.vectorResource(id = R.drawable.down_outline) + Reply -> Icons.Outlined.Comment + Save -> Icons.Outlined.Bookmark + } + } + + @Composable + fun getActionColor(): Color { + return when (this) { + Upvote -> MaterialTheme.colorScheme.primary + Downvote -> MaterialTheme.colorScheme.tertiary + Reply -> MaterialTheme.colorScheme.onPrimary + Save -> MaterialTheme.colorScheme.onTertiary + } + } +} + +enum class SwipeToActionPreset( + val leftActions: List, + val rightActions: List, + val resId: Int +) { + DISABLED(emptyList(), emptyList(), R.string.disabled_swipe_action_preset), + DEFAULT( + listOf(SwipeToActionType.Reply, SwipeToActionType.Save), + listOf(SwipeToActionType.Upvote, SwipeToActionType.Downvote), + R.string.default_swipe_action_preset + ), + LEFT_DOWNVOTE_RIGHT_UPVOTE( + listOf(SwipeToActionType.Downvote, SwipeToActionType.Reply), + listOf(SwipeToActionType.Upvote, SwipeToActionType.Save), + R.string.downvote_on_left_upvote_on_right_swipe_action_preset + ), + ONLY_RIGHT( + emptyList(), + listOf( + SwipeToActionType.Upvote, + SwipeToActionType.Downvote, + SwipeToActionType.Reply, + SwipeToActionType.Save + ), + R.string.only_right_swipe_action_preset + ), + ONLY_LEFT( + listOf( + SwipeToActionType.Upvote, + SwipeToActionType.Downvote, + SwipeToActionType.Reply, + SwipeToActionType.Save + ), + emptyList(), + R.string.only_left_swipe_action_preset + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index 5c0aede12..7c2825517 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyListScope @@ -23,6 +24,7 @@ import androidx.compose.material.icons.outlined.BookmarkBorder import androidx.compose.material.icons.outlined.Comment import androidx.compose.material.icons.outlined.MoreVert import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text @@ -59,12 +61,16 @@ import com.jerboa.datatypes.sampleReplyCommentView import com.jerboa.datatypes.sampleSecondReplyCommentView import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount +import com.jerboa.feat.SwipeToActionPreset +import com.jerboa.feat.SwipeToActionType import com.jerboa.isPostCreator import com.jerboa.ui.components.common.ActionBarButton import com.jerboa.ui.components.common.CommentOrPostNodeHeader import com.jerboa.ui.components.common.MarkdownHelper import com.jerboa.ui.components.common.MyMarkdownText +import com.jerboa.ui.components.common.SwipeToAction import com.jerboa.ui.components.common.VoteGeneric +import com.jerboa.ui.components.common.rememberSwipeActionState import com.jerboa.ui.components.community.CommunityLink import com.jerboa.ui.theme.LARGE_PADDING import com.jerboa.ui.theme.MEDIUM_PADDING @@ -172,6 +178,7 @@ fun CommentBodyPreview() { ) } +@OptIn(ExperimentalMaterial3Api::class) fun LazyListScope.commentNodeItem( node: CommentNode, admins: ImmutableList, @@ -209,6 +216,7 @@ fun LazyListScope.commentNodeItem( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, + swipeToActionPreset: Int ) { val commentView = node.commentView val commentId = commentView.comment.id @@ -229,6 +237,9 @@ fun LazyListScope.commentNodeItem( isExpanded(commentId) && node.children.isEmpty() && commentView.counts.child_count > 0 && !isFlat + val leftActions = SwipeToActionPreset.entries[swipeToActionPreset].leftActions + val rightActions = SwipeToActionPreset.entries[swipeToActionPreset].rightActions + increaseLazyListIndexTracker() // TODO Needs a contentType // possibly "contentNodeItemL${node.depth}" @@ -251,124 +262,159 @@ fun LazyListScope.commentNodeItem( ) } - AnimatedVisibility( - visible = !isCollapsedByParent, - enter = expandVertically(), - exit = shrinkVertically(), - ) { - Column( - modifier = + val swipeState = rememberSwipeActionState( + leftActions = leftActions, + rightActions = rightActions, + onAction = { action -> + when (action) { + SwipeToActionType.Upvote -> { + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Upvote, + ) + onUpvoteClick(commentView) + } + + SwipeToActionType.Downvote -> { + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Downvote, + ) + onDownvoteClick(commentView) + } + + SwipeToActionType.Save -> { + onSaveClick(commentView) + } + + SwipeToActionType.Reply -> { + onReplyClick(commentView) + } + } + }) + + val content: @Composable RowScope.() -> Unit = { + AnimatedVisibility( + visible = !isCollapsedByParent, + enter = expandVertically(), + exit = shrinkVertically(), + ) { + Column( + modifier = Modifier .padding( start = offset, ), - ) { - Column( - modifier = Modifier.border(start = border), ) { - Divider(modifier = Modifier.padding(start = if (node.depth == 0) 0.dp else border.strokeWidth)) Column( - modifier = + modifier = Modifier.border(start = border), + ) { + Divider(modifier = Modifier.padding(start = if (node.depth == 0) 0.dp else border.strokeWidth)) + Column( + modifier = Modifier.padding( start = offset2, end = MEDIUM_PADDING, ), - ) { - if (showPostAndCommunityContext) { - PostAndCommunityContextHeader( - post = commentView.post, - community = commentView.community, - onCommunityClick = onCommunityClick, - onPostClick = onPostClick, - blurNSFW = blurNSFW, - ) - } - CommentNodeHeader( - commentView = commentView, - onPersonClick = onPersonClick, - score = instantScores.value.score, - myVote = instantScores.value.myVote, - onClick = { - onHeaderClick(commentView) - }, - onLongClick = { - onHeaderLongClick(commentView) - }, - collapsedCommentsCount = commentView.counts.child_count, - isExpanded = isExpanded(commentId), - showAvatar = showAvatar, - showScores = showScores, - ) - AnimatedVisibility( - visible = isExpanded(commentId) || showCollapsedCommentContent, - enter = expandVertically(), - exit = shrinkVertically(), ) { - Column { - CommentBody( - comment = commentView.comment, - viewSource = viewSource, - onClick = { onCommentClick(commentView) }, - onLongClick = { v -> - if (v is TextView) { - // Also triggers for long click on links, so we check if link was hit - // Can have selection in viewSource but there are no links there - if (viewSource || (v.selectionStart == -1 && v.selectionEnd == -1)) { - toggleActionBar(commentId) - } - } - true - }, + if (showPostAndCommunityContext) { + PostAndCommunityContextHeader( + post = commentView.post, + community = commentView.community, + onCommunityClick = onCommunityClick, + onPostClick = onPostClick, + blurNSFW = blurNSFW, ) - AnimatedVisibility( - visible = showActionBar(commentId), - enter = expandVertically(), - exit = shrinkVertically(), - ) { - CommentFooterLine( - commentView = commentView, - admins = admins, - moderators = moderators, - instantScores = instantScores.value, - onUpvoteClick = { - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Upvote, - ) - onUpvoteClick(commentView) - }, - onDownvoteClick = { - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Downvote, - ) - onDownvoteClick(commentView) - }, - onViewSourceClick = { - viewSource = !viewSource - }, - onEditCommentClick = onEditCommentClick, - onDeleteCommentClick = onDeleteCommentClick, - onReplyClick = onReplyClick, - onSaveClick = onSaveClick, - onReportClick = onReportClick, - onRemoveClick = onRemoveClick, - onCommentLinkClick = onCommentLinkClick, - onPersonClick = onPersonClick, - onBlockCreatorClick = onBlockCreatorClick, - onClick = { - toggleExpanded(commentId) - }, - onLongClick = { - toggleActionBar(commentId) - }, - account = account, - enableDownVotes = enableDownVotes, - showScores = showScores, + } + CommentNodeHeader( + commentView = commentView, + onPersonClick = onPersonClick, + score = instantScores.value.score, + myVote = instantScores.value.myVote, + onClick = { + onHeaderClick(commentView) + }, + onLongClick = { + onHeaderLongClick(commentView) + }, + collapsedCommentsCount = commentView.counts.child_count, + isExpanded = isExpanded(commentId), + showAvatar = showAvatar, + showScores = showScores, + ) + AnimatedVisibility( + visible = isExpanded(commentId) || showCollapsedCommentContent, + enter = expandVertically(), + exit = shrinkVertically(), + ) { + Column { + CommentBody( + comment = commentView.comment, viewSource = viewSource, + onClick = { onCommentClick(commentView) }, + onLongClick = { v -> + if (v is TextView) { + // Also triggers for long click on links, so we check if link was hit + // Can have selection in viewSource but there are no links there + if (viewSource || (v.selectionStart == -1 && v.selectionEnd == -1)) { + toggleActionBar(commentId) + } + } + true + }, ) + AnimatedVisibility( + visible = showActionBar(commentId), + enter = expandVertically(), + exit = shrinkVertically(), + ) { + CommentFooterLine( + commentView = commentView, + admins = admins, + moderators = moderators, + instantScores = instantScores.value, + onUpvoteClick = { + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Upvote, + ) + onUpvoteClick(commentView) + }, + onDownvoteClick = { + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Downvote, + ) + onDownvoteClick(commentView) + }, + onViewSourceClick = { + viewSource = !viewSource + }, + onEditCommentClick = onEditCommentClick, + onDeleteCommentClick = onDeleteCommentClick, + onReplyClick = onReplyClick, + onSaveClick = onSaveClick, + onReportClick = onReportClick, + onRemoveClick = onRemoveClick, + onCommentLinkClick = onCommentLinkClick, + onPersonClick = onPersonClick, + onBlockCreatorClick = onBlockCreatorClick, + onClick = { + toggleExpanded(commentId) + }, + onLongClick = { + toggleActionBar(commentId) + }, + account = account, + enableDownVotes = enableDownVotes, + showScores = showScores, + viewSource = viewSource, + ) + } } } } @@ -376,6 +422,13 @@ fun LazyListScope.commentNodeItem( } } } + + SwipeToAction( + leftActions = leftActions, + rightActions = rightActions, + swipeableContent = content, + swipeState = swipeState + ) } increaseLazyListIndexTracker() @@ -426,6 +479,7 @@ fun LazyListScope.commentNodeItem( showScores = showScores, admins = admins, moderators = moderators, + swipeToActionPreset = swipeToActionPreset ) } @@ -466,6 +520,7 @@ fun LazyListScope.missingCommentNodeItem( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, + swipeToActionPreset: Int ) { val commentId = node.missingCommentView.commentId @@ -568,6 +623,7 @@ fun LazyListScope.missingCommentNodeItem( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, + swipeToActionPreset = swipeToActionPreset ) } @@ -840,6 +896,7 @@ fun CommentNodesPreview() { blurNSFW = 1, account = AnonAccount, showScores = true, + swipeToActionPreset = 0 ) } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt index e6fe337ba..481b7da57 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt @@ -58,6 +58,7 @@ fun CommentNodes( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, + swipeToActionPreset: Int ) { LazyColumn(state = listState) { commentNodeItems( @@ -97,6 +98,7 @@ fun CommentNodes( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, + swipeToActionPreset = swipeToActionPreset ) item { Spacer(modifier = Modifier.height(100.dp)) @@ -141,6 +143,7 @@ fun LazyListScope.commentNodeItems( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, + swipeToActionPreset: Int ) { nodes.forEach { node -> when (node) { @@ -182,6 +185,7 @@ fun LazyListScope.commentNodeItems( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, + swipeToActionPreset = swipeToActionPreset ) is MissingCommentNode -> @@ -222,6 +226,7 @@ fun LazyListScope.commentNodeItems( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, + swipeToActionPreset = swipeToActionPreset ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index 7f5474998..3bd649523 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -29,25 +29,25 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.unit.dp -import com.jerboa.SwipeActionType +import com.jerboa.feat.SwipeToActionType @Composable @ExperimentalMaterial3Api fun SwipeToAction( - leftActions: List, - rightActions: List, + leftActions: List, + rightActions: List, swipeableContent: @Composable RowScope.() -> Unit, swipeState: DismissState, ) { val haptic = LocalHapticFeedback.current val leftActionsRanges = - remember(leftActions) { SwipeActionType.getActionToRangeList(leftActions) } + remember(leftActions) { SwipeToActionType.getActionToRangeList(leftActions) } val rightActionsRanges = - remember(rightActions) { SwipeActionType.getActionToRangeList(rightActions) } + remember(rightActions) { SwipeToActionType.getActionToRangeList(rightActions) } - fun actionByState(state: DismissState): Pair, SwipeActionType>? { - return when (state.currentValue) { + fun actionByState(state: DismissState): Pair, SwipeToActionType>? { + return when (state.targetValue) { DismissValue.DismissedToEnd -> { leftActionsRanges.findLast { swipeState.progress in it.first } } @@ -60,49 +60,50 @@ fun SwipeToAction( } } - val swipeAction = remember(swipeState) { actionByState(swipeState) } + val swipeAction = + remember(swipeState.progress, swipeState.targetValue) { actionByState(swipeState) } SwipeToDismiss( directions = - remember(leftActions, rightActions) { - setOfNotNull( - if (leftActions.isNotEmpty()) DismissDirection.StartToEnd else null, - if (rightActions.isNotEmpty()) DismissDirection.EndToStart else null, - ) - }, + remember(leftActions, rightActions) { + setOfNotNull( + if (leftActions.isNotEmpty()) DismissDirection.StartToEnd else null, + if (rightActions.isNotEmpty()) DismissDirection.EndToStart else null, + ) + }, state = swipeState, background = { - val lastSwipeAction = remember { mutableStateOf(null) } + val lastSwipeAction = remember { mutableStateOf(null) } val transition = updateTransition(swipeState, label = "swipe state") val color by transition.animateColor( transitionSpec = { - val currentAction = remember(swipeState) { actionByState(swipeState) } + val currentAction = actionByState(this.targetState) // vibrates when icon changes if (lastSwipeAction.value != currentAction?.second) { haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) lastSwipeAction.value = currentAction?.second } - spring(stiffness = 50f) + spring(stiffness = 1000f) }, label = "swipe color animation", targetValueByState = { state -> - val currentAction = remember(state) { actionByState(swipeState) } + val currentAction = actionByState(state) currentAction?.second?.getActionColor() ?: Color.Transparent }, ) Box( modifier = - Modifier - .fillMaxSize(), + Modifier + .fillMaxSize(), ) { Box( modifier = - Modifier - .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) - .fillMaxHeight() - .background(color = color) - .align(if (swipeState.currentValue == DismissValue.DismissedToStart) Alignment.TopEnd else Alignment.TopStart), - contentAlignment = Alignment.CenterStart, + Modifier + .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) + .fillMaxHeight() + .background(color = color) + .align(if (swipeState.targetValue == DismissValue.DismissedToStart) Alignment.TopEnd else Alignment.TopStart), + contentAlignment = if (swipeState.targetValue == DismissValue.DismissedToStart) Alignment.CenterStart else Alignment.CenterEnd, ) { val tint = Color.White val modifier = @@ -129,17 +130,17 @@ fun SwipeToAction( @OptIn(ExperimentalMaterial3Api::class) @Composable fun rememberSwipeActionState( - leftActions: List, - rightActions: List, - onAction: (action: SwipeActionType) -> Unit, + leftActions: List, + rightActions: List, + onAction: (action: SwipeToActionType) -> Unit, ): DismissState { /* This hacky solution is required because confirmValueChange lambda doesn't pass progress state */ val leftActionsRanges = - remember(leftActions) { SwipeActionType.getActionToRangeList(leftActions) } + remember(leftActions) { SwipeToActionType.getActionToRangeList(leftActions) } val rightActionsRanges = - remember(rightActions) { SwipeActionType.getActionToRangeList(rightActions) } + remember(rightActions) { SwipeToActionType.getActionToRangeList(rightActions) } val progressState = remember { mutableFloatStateOf(1.0f) } val dismissState = rememberDismissState( diff --git a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt index 4de4e3fbb..ae0159aea 100644 --- a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt @@ -84,6 +84,7 @@ fun CommunityActivity( showPostLinkPreviews: Boolean, markAsReadOnScroll: Boolean, postActionbarMode: Int, + swipeToActionPreset: Int ) { Log.d("jerboa", "got to community activity") @@ -390,6 +391,7 @@ fun CommunityActivity( showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, showPostAppendRetry = communityViewModel.postsRes is ApiState.AppendingFailure, + swipeToActionPreset = swipeToActionPreset ) } diff --git a/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt index da58ce013..64f101ebc 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt @@ -216,6 +216,7 @@ fun BottomNavActivity( showPostLinkPreviews = appSettings.showPostLinkPreviews, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset ) } @@ -255,6 +256,7 @@ fun BottomNavActivity( drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset ) } @@ -274,6 +276,7 @@ fun BottomNavActivity( drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt index 0ec7e441b..881bd7e28 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt @@ -90,6 +90,7 @@ fun HomeActivity( showPostLinkPreviews: Boolean, markAsReadOnScroll: Boolean, postActionbarMode: Int, + swipeToActionPreset: Int ) { Log.d("jerboa", "got to home activity") @@ -154,6 +155,7 @@ fun HomeActivity( markAsReadOnScroll = markAsReadOnScroll, snackbarHostState = snackbarHostState, postActionbarMode = postActionbarMode, + swipeToActionPreset = swipeToActionPreset ) }, floatingActionButtonPosition = FabPosition.End, @@ -202,6 +204,7 @@ fun MainPostListingsContent( snackbarHostState: SnackbarHostState, markAsReadOnScroll: Boolean, postActionbarMode: Int, + swipeToActionPreset: Int ) { val ctx = LocalContext.current val scope = rememberCoroutineScope() @@ -396,6 +399,7 @@ fun MainPostListingsContent( showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, showPostAppendRetry = homeViewModel.postsRes is ApiState.AppendingFailure, + swipeToActionPreset = swipeToActionPreset ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt index 31845e24b..2b378ddec 100644 --- a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt @@ -117,6 +117,7 @@ fun PersonProfileActivity( drawerState: DrawerState, markAsReadOnScroll: Boolean, postActionbarMode: Int, + swipeToActionPreset: Int, onBack: (() -> Unit)? = null, ) { Log.d("jerboa", "got to person activity") @@ -266,6 +267,7 @@ fun PersonProfileActivity( snackbarHostState = snackbarHostState, showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, + swipeToActionPreset = swipeToActionPreset ) }, ) @@ -301,6 +303,7 @@ fun UserTabs( snackbarHostState: SnackbarHostState, showScores: Boolean, postActionbarMode: Int, + swipeToActionPreset: Int ) { val tabTitles = if (savedMode) { @@ -598,6 +601,7 @@ fun UserTabs( showScores = showScores, postActionbarMode = postActionbarMode, showPostAppendRetry = personProfileViewModel.personDetailsRes is ApiState.AppendingFailure, + swipeToActionPreset = swipeToActionPreset ) } else -> {} @@ -808,6 +812,7 @@ fun UserTabs( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, + swipeToActionPreset = swipeToActionPreset ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt index 29ead0daa..7a695d835 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt @@ -51,12 +51,14 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import androidx.lifecycle.viewmodel.compose.viewModel import arrow.core.Either +import com.jerboa.InstantScores import com.jerboa.JerboaAppState import com.jerboa.PostViewMode import com.jerboa.R import com.jerboa.VoteType import com.jerboa.api.ApiState import com.jerboa.buildCommentsTree +import com.jerboa.calculateNewInstantScores import com.jerboa.datatypes.getLocalizedCommentSortTypeName import com.jerboa.db.entity.isAnon import com.jerboa.feat.doIfReadyElseDisplayInfo @@ -131,6 +133,7 @@ fun PostActivity( blurNSFW: Int, showPostLinkPreview: Boolean, postActionbarMode: Int, + swipeToActionPreset: Int ) { Log.d("jerboa", "got to post activity") @@ -295,6 +298,17 @@ fun PostActivity( .testTag("jerboa:comments"), ) { item(key = "${postView.post.id}_listing", "post_listing") { + val instantScores = + remember { + mutableStateOf( + InstantScores( + myVote = postView.my_vote, + score = postView.counts.score, + upvotes = postView.counts.upvotes, + downvotes = postView.counts.downvotes, + ), + ) + } PostListing( postView = postView, admins = siteViewModel.admins(), @@ -319,6 +333,11 @@ fun PostActivity( ), ) } + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Upvote, + ) }, onDownvoteClick = { pv -> account.doIfReadyElseDisplayInfo( @@ -340,6 +359,11 @@ fun PostActivity( ), ) } + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Downvote, + ) }, onReplyClick = { pv -> appState.toCommentReply( @@ -428,6 +452,7 @@ fun PostActivity( showIfRead = false, showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, + instantScores = instantScores.value ) } @@ -650,6 +675,7 @@ fun PostActivity( }, blurNSFW = blurNSFW, showScores = siteViewModel.showScores(), + swipeToActionPreset = swipeToActionPreset ) item { Spacer(modifier = Modifier.height(100.dp)) diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt index a2aa8f9a9..e6febe246 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt @@ -350,10 +350,10 @@ fun PostTitleAndImageLink( Column( modifier = - Modifier.padding( - vertical = MEDIUM_PADDING, - horizontal = MEDIUM_PADDING, - ), + Modifier.padding( + vertical = MEDIUM_PADDING, + horizontal = MEDIUM_PADDING, + ), ) { // Title of the post PostName( @@ -366,11 +366,11 @@ fun PostTitleAndImageLink( url = url, blur = blurNSFW.toEnum().needBlur(postView), modifier = - Modifier - .combinedClickable( - onClick = { appState.openImageViewer(url) }, - onLongClick = { appState.showLinkPopup(url) }, - ), + Modifier + .combinedClickable( + onClick = { appState.openImageViewer(url) }, + onLongClick = { appState.showLinkPopup(url) }, + ), ) } @@ -464,15 +464,15 @@ fun PostBody( colors = CARD_COLORS, shape = MaterialTheme.shapes.medium, modifier = - Modifier - .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) - .fillMaxWidth(), + Modifier + .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) + .fillMaxWidth(), content = { if (fullBody) { Column( modifier = - Modifier - .padding(MEDIUM_PADDING), + Modifier + .padding(MEDIUM_PADDING), ) { if (viewSource) { SelectionContainer { @@ -633,9 +633,9 @@ fun PostFooterLine( horizontalArrangement = horizontalArrangement, verticalAlignment = Alignment.Bottom, modifier = - modifier - .fillMaxWidth() - .padding(bottom = SMALL_PADDING), + modifier + .fillMaxWidth() + .padding(bottom = SMALL_PADDING), ) { // Right handside shows the comments on the left side if (postActionbar == PostActionbarMode.RightHandShort) { @@ -685,24 +685,24 @@ fun PostFooterLine( } ActionBarButton( icon = - if (postView.saved) { - Icons.Filled.Bookmark - } else { - Icons.Outlined.BookmarkBorder - }, + if (postView.saved) { + Icons.Filled.Bookmark + } else { + Icons.Outlined.BookmarkBorder + }, contentDescription = - if (postView.saved) { - stringResource(R.string.removeBookmark) - } else { - stringResource(R.string.addBookmark) - }, + if (postView.saved) { + stringResource(R.string.removeBookmark) + } else { + stringResource(R.string.addBookmark) + }, onClick = { onSaveClick(postView) }, contentColor = - if (postView.saved) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.onBackground.muted - }, + if (postView.saved) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.onBackground.muted + }, account = account, ) ActionBarButton( @@ -711,7 +711,10 @@ fun PostFooterLine( account = account, onClick = { showMoreOptions = !showMoreOptions }, requiresAccount = false, - modifier = if (postActionbar == PostActionbarMode.LeftHandShort) Modifier.weight(1F, true) else Modifier, + modifier = if (postActionbar == PostActionbarMode.LeftHandShort) Modifier.weight( + 1F, + true + ) else Modifier, ) if (postActionbar == PostActionbarMode.LeftHandShort) { @@ -821,6 +824,13 @@ fun PostFooterLinePreview() { @Preview @Composable fun PreviewPostListingCard() { + val instantScores = + InstantScores( + myVote = samplePostView.my_vote, + score = samplePostView.counts.score, + upvotes = samplePostView.counts.upvotes, + downvotes = samplePostView.counts.downvotes, + ) PostListing( postView = samplePostView, admins = persistentListOf(), @@ -851,12 +861,20 @@ fun PreviewPostListingCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, + instantScores = instantScores ) } @Preview @Composable fun PreviewLinkPostListing() { + val instantScores = + InstantScores( + myVote = sampleLinkPostView.my_vote, + score = sampleLinkPostView.counts.score, + upvotes = sampleLinkPostView.counts.upvotes, + downvotes = sampleLinkPostView.counts.downvotes, + ) PostListing( postView = sampleLinkPostView, admins = persistentListOf(), @@ -887,12 +905,20 @@ fun PreviewLinkPostListing() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, + instantScores = instantScores ) } @Preview @Composable fun PreviewImagePostListingCard() { + val instantScores = + InstantScores( + myVote = sampleImagePostView.my_vote, + score = sampleImagePostView.counts.score, + upvotes = sampleImagePostView.counts.upvotes, + downvotes = sampleImagePostView.counts.downvotes, + ) PostListing( postView = sampleImagePostView, admins = persistentListOf(), @@ -923,12 +949,20 @@ fun PreviewImagePostListingCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, + instantScores = instantScores ) } @Preview @Composable fun PreviewImagePostListingSmallCard() { + val instantScores = + InstantScores( + myVote = sampleImagePostView.my_vote, + score = sampleImagePostView.counts.score, + upvotes = sampleImagePostView.counts.upvotes, + downvotes = sampleImagePostView.counts.downvotes, + ) PostListing( postView = sampleImagePostView, admins = persistentListOf(), @@ -959,12 +993,20 @@ fun PreviewImagePostListingSmallCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, + instantScores = instantScores ) } @Preview @Composable fun PreviewLinkNoThumbnailPostListing() { + val instantScores = + InstantScores( + myVote = sampleLinkNoThumbnailPostView.my_vote, + score = sampleLinkNoThumbnailPostView.counts.score, + upvotes = sampleLinkNoThumbnailPostView.counts.upvotes, + downvotes = sampleLinkNoThumbnailPostView.counts.downvotes, + ) PostListing( postView = sampleLinkNoThumbnailPostView, admins = persistentListOf(), @@ -995,6 +1037,7 @@ fun PreviewLinkNoThumbnailPostListing() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, + instantScores = instantScores ) } @@ -1031,20 +1074,8 @@ fun PostListing( showIfRead: Boolean, showScores: Boolean, postActionbarMode: Int, + instantScores: InstantScores ) { - // This stores vote data - val instantScores = - remember { - mutableStateOf( - InstantScores( - myVote = postView.my_vote, - score = postView.counts.score, - upvotes = postView.counts.upvotes, - downvotes = postView.counts.downvotes, - ), - ) - } - var viewSource by remember { mutableStateOf(false) } when (postViewMode) { @@ -1053,23 +1084,9 @@ fun PostListing( postView = postView, admins = admins, moderators = moderators, - instantScores = instantScores.value, - onUpvoteClick = { - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Upvote, - ) - onUpvoteClick(postView) - }, - onDownvoteClick = { - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Downvote, - ) - onDownvoteClick(postView) - }, + instantScores = instantScores, + onUpvoteClick = remember { { onUpvoteClick(postView) } }, + onDownvoteClick = remember { { onDownvoteClick(postView) } }, onReplyClick = onReplyClick, onPostClick = onPostClick, onSaveClick = onSaveClick, @@ -1106,23 +1123,9 @@ fun PostListing( postView = postView, admins = admins, moderators = moderators, - instantScores = instantScores.value, - onUpvoteClick = { - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Upvote, - ) - onUpvoteClick(postView) - }, - onDownvoteClick = { - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Downvote, - ) - onDownvoteClick(postView) - }, + instantScores = instantScores, + onUpvoteClick = remember { { onUpvoteClick(postView) } }, + onDownvoteClick = remember { { onDownvoteClick(postView) } }, onReplyClick = onReplyClick, onPostClick = onPostClick, onSaveClick = onSaveClick, @@ -1156,23 +1159,9 @@ fun PostListing( PostViewMode.List -> PostListingList( postView = postView, - instantScores = instantScores.value, - onUpvoteClick = { - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Upvote, - ) - onUpvoteClick(postView) - }, - onDownvoteClick = { - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Downvote, - ) - onDownvoteClick(postView) - }, + instantScores = instantScores, + onUpvoteClick = remember { { onUpvoteClick(postView) } }, + onDownvoteClick = remember { { onDownvoteClick(postView) } }, onPostClick = onPostClick, showCommunityName = showCommunityName, account = account, @@ -1201,9 +1190,9 @@ fun PostVotingTile( Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = - Modifier - .fillMaxHeight() - .padding(end = MEDIUM_PADDING), + Modifier + .fillMaxHeight() + .padding(end = MEDIUM_PADDING), ) { VoteGeneric( myVote = instantScores.myVote, @@ -1261,19 +1250,19 @@ fun PostListingList( ) { Column( modifier = - Modifier - .padding( - horizontal = MEDIUM_PADDING, - vertical = MEDIUM_PADDING, - ) - .testTag("jerboa:post"), + Modifier + .padding( + horizontal = MEDIUM_PADDING, + vertical = MEDIUM_PADDING, + ) + .testTag("jerboa:post"), ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = - Arrangement.spacedBy( - SMALL_PADDING, - ), + Arrangement.spacedBy( + SMALL_PADDING, + ), ) { if (showVotingArrowsInListView) { PostVotingTile( @@ -1287,9 +1276,9 @@ fun PostListingList( } Column( modifier = - Modifier - .weight(1f) - .clickable { onPostClick(postView) }, + Modifier + .weight(1f) + .clickable { onPostClick(postView) }, verticalArrangement = Arrangement.spacedBy(SMALL_PADDING), ) { PostName(postView = postView, showIfRead = showIfRead) @@ -1346,10 +1335,10 @@ fun PostListingList( } Text( text = - stringResource( - R.string.post_listing_comments_count, - postView.counts.comments, - ), + stringResource( + R.string.post_listing_comments_count, + postView.counts.comments, + ), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onBackground.muted, ) @@ -1437,14 +1426,14 @@ private fun ThumbnailTile( painter = painterResource(id = R.drawable.triangle), contentDescription = null, modifier = - Modifier - .size(THUMBNAIL_CARET_SIZE) - .align(Alignment.BottomEnd), + Modifier + .size(THUMBNAIL_CARET_SIZE) + .align(Alignment.BottomEnd), tint = - when (postType) { - PostType.Video -> MaterialTheme.jerboaColorScheme.videoHighlight - else -> MaterialTheme.jerboaColorScheme.imageHighlight - }, + when (postType) { + PostType.Video -> MaterialTheme.jerboaColorScheme.videoHighlight + else -> MaterialTheme.jerboaColorScheme.imageHighlight + }, ) } } @@ -1549,10 +1538,10 @@ fun PostListingCard( ) { Column( modifier = - Modifier - .padding(vertical = MEDIUM_PADDING) - .clickable { onPostClick(postView) } - .testTag("jerboa:post"), + Modifier + .padding(vertical = MEDIUM_PADDING) + .clickable { onPostClick(postView) } + .testTag("jerboa:post"), // see https://stackoverflow.com/questions/77010371/prevent-popup-from-adding-padding-in-a-column-with-arrangement-spacedbylarge-p // verticalArrangement = Arrangement.spacedBy(LARGE_PADDING), ) { @@ -1633,9 +1622,9 @@ fun MetadataCard(post: Post) { OutlinedCard( shape = MaterialTheme.shapes.medium, modifier = - Modifier - .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) - .fillMaxWidth(), + Modifier + .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) + .fillMaxWidth(), content = { Column( modifier = Modifier.padding(MEDIUM_PADDING), diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt index 4ca37c7bf..ce40481ec 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt @@ -1,6 +1,7 @@ package com.jerboa.ui.components.post import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -8,25 +9,34 @@ import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.jerboa.InstantScores import com.jerboa.JerboaAppState import com.jerboa.PostViewMode +import com.jerboa.feat.SwipeToActionType +import com.jerboa.VoteType +import com.jerboa.calculateNewInstantScores import com.jerboa.datatypes.sampleLinkPostView import com.jerboa.datatypes.samplePostView import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.isScrolledToEnd import com.jerboa.rememberJerboaAppState import com.jerboa.ui.components.common.RetryLoadingPosts +import com.jerboa.ui.components.common.SwipeToAction +import com.jerboa.ui.components.common.rememberSwipeActionState import com.jerboa.ui.components.common.simpleVerticalScrollbar import com.jerboa.ui.theme.SMALL_PADDING import it.vercruysse.lemmyapi.v0x19.datatypes.Community @@ -36,6 +46,7 @@ import it.vercruysse.lemmyapi.v0x19.datatypes.PostView import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf +@OptIn(ExperimentalMaterial3Api::class) @Composable fun PostListings( posts: ImmutableList, @@ -73,15 +84,18 @@ fun PostListings( showScores: Boolean, postActionbarMode: Int, showPostAppendRetry: Boolean, + swipeToActionPreset: Int ) { + val leftActions = SwipeToActionPreset.entries[swipeToActionPreset].leftActions + val rightActions = SwipeToActionPreset.entries[swipeToActionPreset].rightActions LazyColumn( state = listState, modifier = - Modifier - .padding(padding) - .fillMaxSize() - .simpleVerticalScrollbar(listState) - .testTag("jerboa:posts"), + Modifier + .padding(padding) + .fillMaxSize() + .simpleVerticalScrollbar(listState) + .testTag("jerboa:posts"), ) { item(contentType = "aboveContent") { contentAboveListings() @@ -91,47 +105,114 @@ fun PostListings( items = posts, contentType = { _, _ -> "Post" }, ) { index, postView -> - PostListing( - postView = postView, - admins = admins, - moderators = moderators, - useCustomTabs = useCustomTabs, - usePrivateTabs = usePrivateTabs, - onUpvoteClick = onUpvoteClick, - onDownvoteClick = onDownvoteClick, - onPostClick = onPostClick, - onSaveClick = onSaveClick, - onCommunityClick = onCommunityClick, - onEditPostClick = onEditPostClick, - onDeletePostClick = onDeletePostClick, - onReportClick = onReportClick, - onRemoveClick = onRemoveClick, - onLockPostClick = onLockPostClick, - onPersonClick = onPersonClick, - showCommunityName = showCommunityName, - fullBody = false, - account = account, - postViewMode = postViewMode, - showVotingArrowsInListView = showVotingArrowsInListView, - enableDownVotes = enableDownVotes, - showAvatar = showAvatar, - blurNSFW = blurNSFW, - appState = appState, - showPostLinkPreview = showPostLinkPreviews, - showIfRead = showIfRead, - showScores = showScores, - postActionbarMode = postActionbarMode, - ).let { - if (!postView.read && markAsReadOnScroll) { - DisposableEffect(key1 = postView.post.id) { - onDispose { - if (listState.isScrollInProgress && index < listState.firstVisibleItemIndex) { - onMarkAsRead(postView) + val instantScores = + remember { + mutableStateOf( + InstantScores( + myVote = postView.my_vote, + score = postView.counts.score, + upvotes = postView.counts.upvotes, + downvotes = postView.counts.downvotes, + ), + ) + } + val swipeState = rememberSwipeActionState( + leftActions = leftActions, + rightActions = rightActions, + onAction = { action -> + when (action) { + SwipeToActionType.Upvote -> { + onUpvoteClick(postView) + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Upvote, + ) + } + + SwipeToActionType.Downvote -> { + onDownvoteClick(postView) + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Downvote, + ) + } + + SwipeToActionType.Save -> { + onSaveClick(postView) + } + + SwipeToActionType.Reply -> { + onPostClick(postView) + } + } + }) + + val content: @Composable RowScope.() -> Unit = { + PostListing( + postView = postView, + admins = admins, + moderators = moderators, + useCustomTabs = useCustomTabs, + usePrivateTabs = usePrivateTabs, + onUpvoteClick = { + onUpvoteClick(it) + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Upvote, + ) + }, + onDownvoteClick = { + onDownvoteClick(it) + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Downvote, + ) + }, + onPostClick = onPostClick, + onSaveClick = onSaveClick, + onCommunityClick = onCommunityClick, + onEditPostClick = onEditPostClick, + onDeletePostClick = onDeletePostClick, + onReportClick = onReportClick, + onRemoveClick = onRemoveClick, + onLockPostClick = onLockPostClick, + onPersonClick = onPersonClick, + showCommunityName = showCommunityName, + fullBody = false, + account = account, + postViewMode = postViewMode, + showVotingArrowsInListView = showVotingArrowsInListView, + enableDownVotes = enableDownVotes, + showAvatar = showAvatar, + blurNSFW = blurNSFW, + appState = appState, + showPostLinkPreview = showPostLinkPreviews, + showIfRead = showIfRead, + showScores = showScores, + postActionbarMode = postActionbarMode, + instantScores = instantScores.value + ).let { + if (!postView.read && markAsReadOnScroll) { + DisposableEffect(key1 = postView.post.id) { + onDispose { + if (listState.isScrollInProgress && index < listState.firstVisibleItemIndex) { + onMarkAsRead(postView) + } } } } } } + SwipeToAction( + leftActions = leftActions, + rightActions = rightActions, + swipeableContent = content, + swipeState = swipeState + ) Divider(modifier = Modifier.padding(bottom = SMALL_PADDING)) } @@ -193,5 +274,6 @@ fun PreviewPostListings() { showScores = true, postActionbarMode = 0, showPostAppendRetry = false, + swipeToActionPreset = 0 ) } diff --git a/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt b/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt index e41cb3106..391aa37b7 100644 --- a/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt @@ -45,6 +45,7 @@ import com.jerboa.feat.BackConfirmationMode import com.jerboa.feat.BlurTypes import com.jerboa.feat.PostActionbarMode import com.jerboa.feat.PostNavigationGestureMode +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.getLangPreferenceDropdownEntries import com.jerboa.matchLocale import com.jerboa.model.AppSettingsViewModel @@ -107,6 +108,8 @@ fun LookAndFeelActivity( val markAsReadOnScroll = rememberBooleanSettingState(settings.markAsReadOnScroll) val autoPlayGifs = rememberBooleanSettingState(settings.autoPlayGifs) + val swipeToActionPreset = rememberIntSettingState(settings.swipeToActionPreset) + fun updateAppSettings() { appSettingsViewModel.update( AppSettings( @@ -133,6 +136,7 @@ fun LookAndFeelActivity( postActionbarMode = postActionbarMode.value, autoPlayGifs = autoPlayGifs.value, postNavigationGestureMode = postNavigationGestureModeState.value, + swipeToActionPreset = swipeToActionPreset.value ), ) } @@ -145,9 +149,9 @@ fun LookAndFeelActivity( content = { padding -> Column( modifier = - Modifier - .verticalScroll(scrollState) - .padding(padding), + Modifier + .verticalScroll(scrollState) + .padding(padding), ) { SettingsListDropdown( title = { @@ -302,6 +306,18 @@ fun LookAndFeelActivity( items = BlurTypes.entries.map { stringResource(it.resId) }, onItemSelected = { _, _ -> updateAppSettings() }, ) + SettingsListDropdown( + state = swipeToActionPreset, + icon = { + Icon( + imageVector = Icons.Outlined.Swipe, + contentDescription = null, + ) + }, + title = { Text(stringResource(id = R.string.swipe_to_action_presets)) }, + items = SwipeToActionPreset.entries.map { stringResource(it.resId) }, + onItemSelected = { _, _ -> updateAppSettings() }, + ) SettingsCheckbox( state = showBottomNavState, title = { diff --git a/app/src/main/java/com/jerboa/ui/theme/Color.kt b/app/src/main/java/com/jerboa/ui/theme/Color.kt index 1b47e9488..74e80c058 100644 --- a/app/src/main/java/com/jerboa/ui/theme/Color.kt +++ b/app/src/main/java/com/jerboa/ui/theme/Color.kt @@ -373,10 +373,6 @@ fun crimson(): Pair { val md_theme_dark_scrim = Color(0xFF000000) val jerboa_image_highlight = Color(0xCCD1D1D1) val jerboa_video_highlight = Color(0xCCC20000) - val jerboa_upvote_swipe = Color(0xff4caf50) - val jerboa_downvote_swipe = Color(0xfff44336) - val jerboa_save_swipe = Color(0xff448aff) - val jerboa_reply_swipe = Color(0xffffa000) // val seed = Color(0xFF78B0FF) @@ -451,21 +447,13 @@ fun crimson(): Pair { material = light, imageHighlight = jerboa_image_highlight, videoHighlight = jerboa_video_highlight, - upvoteSwipe = jerboa_upvote_swipe, - downvoteSwipe = jerboa_downvote_swipe, - saveSwipe = jerboa_save_swipe, - replySwipe = jerboa_reply_swipe, ) val jerboaDark = JerboaColorScheme( material = dark, imageHighlight = jerboa_image_highlight, - videoHighlight = jerboa_video_highlight, - upvoteSwipe = jerboa_upvote_swipe, - downvoteSwipe = jerboa_downvote_swipe, - saveSwipe = jerboa_save_swipe, - replySwipe = jerboa_reply_swipe, + videoHighlight = jerboa_video_highlight ) return Pair(jerboaLight, jerboaDark) diff --git a/app/src/main/java/com/jerboa/ui/theme/JerboaColorScheme.kt b/app/src/main/java/com/jerboa/ui/theme/JerboaColorScheme.kt index 527d2b39d..22de8e77d 100644 --- a/app/src/main/java/com/jerboa/ui/theme/JerboaColorScheme.kt +++ b/app/src/main/java/com/jerboa/ui/theme/JerboaColorScheme.kt @@ -11,8 +11,4 @@ data class JerboaColorScheme( val material: ColorScheme = darkColorScheme(), // the default Material color scheme val imageHighlight: Color = Color(0xCCD1D1D1), // the color that highlights an image thumb val videoHighlight: Color = Color(0xCCC20000), // the color that highlights a video thumb - val upvoteSwipe: Color = Color(0xff4caf50), // the background color for upvote when swiping - val downvoteSwipe: Color = Color(0xfff44336), // the background color for downvote when swiping - val saveSwipe: Color = Color(0xff448aff), // the background color for share when swiping - val replySwipe: Color = Color(0xffffa000), // the background color for reply when swiping ) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 26f8d6964..02880710e 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -158,6 +158,7 @@ Пожаловаться на пользователя Загрузить изображение Удалено + Удалено Выделено в сообществе Выделено локально Перейти в сообщество @@ -203,7 +204,7 @@ Присоединяйтесь к c/jerboa Открытый исходный код Исходный код - Jerboa — это свободное программное обеспечение с открытым исходным кодом, распространяемое под лицензией + "Jerboa — это свободное программное обеспечение с открытым исходным кодом, распространяемое под лицензией " GNU Affero General Public License v3.0 Поддержка Версия %1$s @@ -235,8 +236,8 @@ Сначала авторизуйтесь Поддержать Опустить - Вы повысили пост - Вы понизили пост + Вы поддержали пост + Вы снизили оценку поста Сохраненное изображение Сохранение изображения… Доступ запрещен @@ -269,7 +270,6 @@ Показывать рейтинги Подписки Добавить в закладки - . Перейти в закладки Перейти на главный экран Перейти во входящее @@ -369,6 +369,10 @@ Поделится Включить 2FA Запустить ссылку 2FA + Длинная панель + Короткая панель для левшей + Короткая панель для правшей + Режим панели действий поста Автоматическое воспроизведение GIF Разблокировать сообщество %1s заблокирован @@ -397,5 +401,22 @@ Не удалось разобрать дату Запись об этом комментарии отсутствует Версия (%s) не поддерживается + Комментарий удалён + Комментарий восстановлен + Пост удалён + Пост восстановлен + Удалить комментарий + Вернуть комментарий + Удалить пост + Вернуть пост + Заморозить пост + Разморозить бост + Введите причину + Преднастройки для смахивающего жеста + Отключить + По умолчанию + Отриц. - слева, положит. - справа + Только справа + Только слева \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 56b90c83a..5ebc5d755 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -415,4 +415,10 @@ Lock Post Unlock Post Type your reason + Swipe gesture presets + Disabled + Default (votes on right, share/reply on left) + Left-right votes + Only right swipe + Only left swipe From edd1b7e6f350352f7e984af8b650732c857f8bd1 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 23 Jan 2024 00:28:27 +0300 Subject: [PATCH 03/19] Fix kotlin format --- app/src/main/java/com/jerboa/MainActivity.kt | 12 +- app/src/main/java/com/jerboa/db/AppDB.kt | 2 +- .../java/com/jerboa/db/AppDBMigrations.kt | 2 +- .../java/com/jerboa/feat/SwipeToActionType.kt | 20 +-- .../ui/components/comment/CommentNode.kt | 86 +++++----- .../ui/components/comment/CommentNodes.kt | 10 +- .../ui/components/common/SwipeToAction.kt | 26 +-- .../components/community/CommunityActivity.kt | 4 +- .../ui/components/home/BottomNavActivity.kt | 6 +- .../jerboa/ui/components/home/HomeActivity.kt | 8 +- .../person/PersonProfileActivity.kt | 8 +- .../jerboa/ui/components/post/PostActivity.kt | 6 +- .../jerboa/ui/components/post/PostListing.kt | 156 +++++++++--------- .../jerboa/ui/components/post/PostListings.kt | 78 ++++----- .../lookandfeel/LookAndFeelActivity.kt | 8 +- .../main/java/com/jerboa/ui/theme/Color.kt | 2 +- app/src/main/res/values/strings.xml | 1 - 17 files changed, 221 insertions(+), 214 deletions(-) diff --git a/app/src/main/java/com/jerboa/MainActivity.kt b/app/src/main/java/com/jerboa/MainActivity.kt index b5725252c..6812ac8d0 100644 --- a/app/src/main/java/com/jerboa/MainActivity.kt +++ b/app/src/main/java/com/jerboa/MainActivity.kt @@ -233,7 +233,7 @@ class MainActivity : AppCompatActivity() { showPostLinkPreviews = appSettings.showPostLinkPreviews, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset + swipeToActionPreset = appSettings.swipeToActionPreset, ) } @@ -277,7 +277,7 @@ class MainActivity : AppCompatActivity() { showPostLinkPreviews = appSettings.showPostLinkPreviews, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset + swipeToActionPreset = appSettings.swipeToActionPreset, ) } @@ -318,7 +318,7 @@ class MainActivity : AppCompatActivity() { onBack = appState::popBackStack, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset + swipeToActionPreset = appSettings.swipeToActionPreset, ) } @@ -356,7 +356,7 @@ class MainActivity : AppCompatActivity() { drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset + swipeToActionPreset = appSettings.swipeToActionPreset, ) } @@ -468,7 +468,7 @@ class MainActivity : AppCompatActivity() { blurNSFW = appSettings.blurNSFW, showPostLinkPreview = appSettings.showPostLinkPreviews, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset + swipeToActionPreset = appSettings.swipeToActionPreset, ) } } @@ -502,7 +502,7 @@ class MainActivity : AppCompatActivity() { blurNSFW = appSettings.blurNSFW, showPostLinkPreview = appSettings.showPostLinkPreviews, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset + swipeToActionPreset = appSettings.swipeToActionPreset, ) } diff --git a/app/src/main/java/com/jerboa/db/AppDB.kt b/app/src/main/java/com/jerboa/db/AppDB.kt index 811c48478..ec1b9c417 100644 --- a/app/src/main/java/com/jerboa/db/AppDB.kt +++ b/app/src/main/java/com/jerboa/db/AppDB.kt @@ -39,7 +39,7 @@ val APP_SETTINGS_DEFAULT = showPostLinkPreviews = true, postActionbarMode = 0, autoPlayGifs = false, - swipeToActionPreset = 1 + swipeToActionPreset = 1, ) @Database( diff --git a/app/src/main/java/com/jerboa/db/AppDBMigrations.kt b/app/src/main/java/com/jerboa/db/AppDBMigrations.kt index d9bd8f540..4da3f5216 100644 --- a/app/src/main/java/com/jerboa/db/AppDBMigrations.kt +++ b/app/src/main/java/com/jerboa/db/AppDBMigrations.kt @@ -437,5 +437,5 @@ val MIGRATIONS_LIST = MIGRATION_25_26, MIGRATION_26_25, MIGRATION_26_27, - MIGRATION_27_26 + MIGRATION_27_26, ) diff --git a/app/src/main/java/com/jerboa/feat/SwipeToActionType.kt b/app/src/main/java/com/jerboa/feat/SwipeToActionType.kt index c4342adce..f64712a1b 100644 --- a/app/src/main/java/com/jerboa/feat/SwipeToActionType.kt +++ b/app/src/main/java/com/jerboa/feat/SwipeToActionType.kt @@ -19,7 +19,7 @@ enum class SwipeToActionType() { companion object { fun getActionToRangeList(actions: List): List, SwipeToActionType>> { - val delta = if(actions.size > 2) 0.14f else 0.18f + val delta = if (actions.size > 2) 0.14f else 0.18f return actions.mapIndexed { index, it -> (0.1f + delta * index) .rangeUntil(if (index == actions.size - 1) 1f else (0.1f + delta * (index + 1))) to it @@ -59,18 +59,18 @@ enum class SwipeToActionType() { enum class SwipeToActionPreset( val leftActions: List, val rightActions: List, - val resId: Int + val resId: Int, ) { DISABLED(emptyList(), emptyList(), R.string.disabled_swipe_action_preset), DEFAULT( listOf(SwipeToActionType.Reply, SwipeToActionType.Save), listOf(SwipeToActionType.Upvote, SwipeToActionType.Downvote), - R.string.default_swipe_action_preset + R.string.default_swipe_action_preset, ), LEFT_DOWNVOTE_RIGHT_UPVOTE( listOf(SwipeToActionType.Downvote, SwipeToActionType.Reply), listOf(SwipeToActionType.Upvote, SwipeToActionType.Save), - R.string.downvote_on_left_upvote_on_right_swipe_action_preset + R.string.downvote_on_left_upvote_on_right_swipe_action_preset, ), ONLY_RIGHT( emptyList(), @@ -78,18 +78,18 @@ enum class SwipeToActionPreset( SwipeToActionType.Upvote, SwipeToActionType.Downvote, SwipeToActionType.Reply, - SwipeToActionType.Save + SwipeToActionType.Save, ), - R.string.only_right_swipe_action_preset + R.string.only_right_swipe_action_preset, ), ONLY_LEFT( listOf( SwipeToActionType.Upvote, SwipeToActionType.Downvote, SwipeToActionType.Reply, - SwipeToActionType.Save + SwipeToActionType.Save, ), emptyList(), - R.string.only_left_swipe_action_preset - ) -} \ No newline at end of file + R.string.only_left_swipe_action_preset, + ), +} diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index 7c2825517..a19d19eb8 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -216,7 +216,7 @@ fun LazyListScope.commentNodeItem( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: Int + swipeToActionPreset: Int, ) { val commentView = node.commentView val commentId = commentView.comment.id @@ -262,38 +262,40 @@ fun LazyListScope.commentNodeItem( ) } - val swipeState = rememberSwipeActionState( - leftActions = leftActions, - rightActions = rightActions, - onAction = { action -> - when (action) { - SwipeToActionType.Upvote -> { - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Upvote, - ) - onUpvoteClick(commentView) - } + val swipeState = + rememberSwipeActionState( + leftActions = leftActions, + rightActions = rightActions, + onAction = { action -> + when (action) { + SwipeToActionType.Upvote -> { + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Upvote, + ) + onUpvoteClick(commentView) + } - SwipeToActionType.Downvote -> { - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Downvote, - ) - onDownvoteClick(commentView) - } + SwipeToActionType.Downvote -> { + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Downvote, + ) + onDownvoteClick(commentView) + } - SwipeToActionType.Save -> { - onSaveClick(commentView) - } + SwipeToActionType.Save -> { + onSaveClick(commentView) + } - SwipeToActionType.Reply -> { - onReplyClick(commentView) + SwipeToActionType.Reply -> { + onReplyClick(commentView) + } } - } - }) + }, + ) val content: @Composable RowScope.() -> Unit = { AnimatedVisibility( @@ -303,10 +305,10 @@ fun LazyListScope.commentNodeItem( ) { Column( modifier = - Modifier - .padding( - start = offset, - ), + Modifier + .padding( + start = offset, + ), ) { Column( modifier = Modifier.border(start = border), @@ -314,10 +316,10 @@ fun LazyListScope.commentNodeItem( Divider(modifier = Modifier.padding(start = if (node.depth == 0) 0.dp else border.strokeWidth)) Column( modifier = - Modifier.padding( - start = offset2, - end = MEDIUM_PADDING, - ), + Modifier.padding( + start = offset2, + end = MEDIUM_PADDING, + ), ) { if (showPostAndCommunityContext) { PostAndCommunityContextHeader( @@ -427,7 +429,7 @@ fun LazyListScope.commentNodeItem( leftActions = leftActions, rightActions = rightActions, swipeableContent = content, - swipeState = swipeState + swipeState = swipeState, ) } @@ -479,7 +481,7 @@ fun LazyListScope.commentNodeItem( showScores = showScores, admins = admins, moderators = moderators, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } @@ -520,7 +522,7 @@ fun LazyListScope.missingCommentNodeItem( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: Int + swipeToActionPreset: Int, ) { val commentId = node.missingCommentView.commentId @@ -623,7 +625,7 @@ fun LazyListScope.missingCommentNodeItem( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } @@ -896,7 +898,7 @@ fun CommentNodesPreview() { blurNSFW = 1, account = AnonAccount, showScores = true, - swipeToActionPreset = 0 + swipeToActionPreset = 0, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt index 481b7da57..06206470a 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt @@ -58,7 +58,7 @@ fun CommentNodes( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: Int + swipeToActionPreset: Int, ) { LazyColumn(state = listState) { commentNodeItems( @@ -98,7 +98,7 @@ fun CommentNodes( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) item { Spacer(modifier = Modifier.height(100.dp)) @@ -143,7 +143,7 @@ fun LazyListScope.commentNodeItems( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: Int + swipeToActionPreset: Int, ) { nodes.forEach { node -> when (node) { @@ -185,7 +185,7 @@ fun LazyListScope.commentNodeItems( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) is MissingCommentNode -> @@ -226,7 +226,7 @@ fun LazyListScope.commentNodeItems( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index 3bd649523..dcdf7bb90 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -65,12 +65,12 @@ fun SwipeToAction( SwipeToDismiss( directions = - remember(leftActions, rightActions) { - setOfNotNull( - if (leftActions.isNotEmpty()) DismissDirection.StartToEnd else null, - if (rightActions.isNotEmpty()) DismissDirection.EndToStart else null, - ) - }, + remember(leftActions, rightActions) { + setOfNotNull( + if (leftActions.isNotEmpty()) DismissDirection.StartToEnd else null, + if (rightActions.isNotEmpty()) DismissDirection.EndToStart else null, + ) + }, state = swipeState, background = { val lastSwipeAction = remember { mutableStateOf(null) } @@ -93,16 +93,16 @@ fun SwipeToAction( ) Box( modifier = - Modifier - .fillMaxSize(), + Modifier + .fillMaxSize(), ) { Box( modifier = - Modifier - .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) - .fillMaxHeight() - .background(color = color) - .align(if (swipeState.targetValue == DismissValue.DismissedToStart) Alignment.TopEnd else Alignment.TopStart), + Modifier + .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) + .fillMaxHeight() + .background(color = color) + .align(if (swipeState.targetValue == DismissValue.DismissedToStart) Alignment.TopEnd else Alignment.TopStart), contentAlignment = if (swipeState.targetValue == DismissValue.DismissedToStart) Alignment.CenterStart else Alignment.CenterEnd, ) { val tint = Color.White diff --git a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt index bb6051184..2f0334642 100644 --- a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt @@ -85,7 +85,7 @@ fun CommunityActivity( showPostLinkPreviews: Boolean, markAsReadOnScroll: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int + swipeToActionPreset: Int, ) { Log.d("jerboa", "got to community activity") @@ -410,7 +410,7 @@ fun CommunityActivity( showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, showPostAppendRetry = communityViewModel.postsRes is ApiState.AppendingFailure, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt index 64f101ebc..2705a049c 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt @@ -216,7 +216,7 @@ fun BottomNavActivity( showPostLinkPreviews = appSettings.showPostLinkPreviews, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset + swipeToActionPreset = appSettings.swipeToActionPreset, ) } @@ -256,7 +256,7 @@ fun BottomNavActivity( drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset + swipeToActionPreset = appSettings.swipeToActionPreset, ) } @@ -276,7 +276,7 @@ fun BottomNavActivity( drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset + swipeToActionPreset = appSettings.swipeToActionPreset, ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt index 0d5f27875..37d4b4a8a 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt @@ -91,7 +91,7 @@ fun HomeActivity( showPostLinkPreviews: Boolean, markAsReadOnScroll: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int + swipeToActionPreset: Int, ) { Log.d("jerboa", "got to home activity") @@ -156,7 +156,7 @@ fun HomeActivity( markAsReadOnScroll = markAsReadOnScroll, snackbarHostState = snackbarHostState, postActionbarMode = postActionbarMode, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) }, floatingActionButtonPosition = FabPosition.End, @@ -205,7 +205,7 @@ fun MainPostListingsContent( snackbarHostState: SnackbarHostState, markAsReadOnScroll: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int + swipeToActionPreset: Int, ) { val ctx = LocalContext.current val scope = rememberCoroutineScope() @@ -417,7 +417,7 @@ fun MainPostListingsContent( showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, showPostAppendRetry = homeViewModel.postsRes is ApiState.AppendingFailure, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt index 12c52d5ab..209b7bbdd 100644 --- a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt @@ -268,7 +268,7 @@ fun PersonProfileActivity( snackbarHostState = snackbarHostState, showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) }, ) @@ -304,7 +304,7 @@ fun UserTabs( snackbarHostState: SnackbarHostState, showScores: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int + swipeToActionPreset: Int, ) { val tabTitles = if (savedMode) { @@ -619,7 +619,7 @@ fun UserTabs( showScores = showScores, postActionbarMode = postActionbarMode, showPostAppendRetry = personProfileViewModel.personDetailsRes is ApiState.AppendingFailure, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } else -> {} @@ -830,7 +830,7 @@ fun UserTabs( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt index 7c79c86b8..fc79b8b45 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt @@ -133,7 +133,7 @@ fun PostActivity( blurNSFW: Int, showPostLinkPreview: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int + swipeToActionPreset: Int, ) { Log.d("jerboa", "got to post activity") @@ -470,7 +470,7 @@ fun PostActivity( showIfRead = false, showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, - instantScores = instantScores.value + instantScores = instantScores.value, ) } @@ -693,7 +693,7 @@ fun PostActivity( }, blurNSFW = blurNSFW, showScores = siteViewModel.showScores(), - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) item { Spacer(modifier = Modifier.height(100.dp)) diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt index 7b2564760..8888b6907 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt @@ -64,7 +64,6 @@ import com.jerboa.R import com.jerboa.VoteType import com.jerboa.amAdmin import com.jerboa.amMod -import com.jerboa.calculateNewInstantScores import com.jerboa.canMod import com.jerboa.datatypes.PostFeatureData import com.jerboa.datatypes.sampleImagePostView @@ -351,10 +350,10 @@ fun PostTitleAndImageLink( Column( modifier = - Modifier.padding( - vertical = MEDIUM_PADDING, - horizontal = MEDIUM_PADDING, - ), + Modifier.padding( + vertical = MEDIUM_PADDING, + horizontal = MEDIUM_PADDING, + ), ) { // Title of the post PostName( @@ -367,11 +366,11 @@ fun PostTitleAndImageLink( url = url, blur = blurNSFW.toEnum().needBlur(postView), modifier = - Modifier - .combinedClickable( - onClick = { appState.openImageViewer(url) }, - onLongClick = { appState.showLinkPopup(url) }, - ), + Modifier + .combinedClickable( + onClick = { appState.openImageViewer(url) }, + onLongClick = { appState.showLinkPopup(url) }, + ), ) } @@ -465,15 +464,15 @@ fun PostBody( colors = CARD_COLORS, shape = MaterialTheme.shapes.medium, modifier = - Modifier - .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) - .fillMaxWidth(), + Modifier + .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) + .fillMaxWidth(), content = { if (fullBody) { Column( modifier = - Modifier - .padding(MEDIUM_PADDING), + Modifier + .padding(MEDIUM_PADDING), ) { if (viewSource) { SelectionContainer { @@ -636,9 +635,9 @@ fun PostFooterLine( horizontalArrangement = horizontalArrangement, verticalAlignment = Alignment.Bottom, modifier = - modifier - .fillMaxWidth() - .padding(bottom = SMALL_PADDING), + modifier + .fillMaxWidth() + .padding(bottom = SMALL_PADDING), ) { // Right handside shows the comments on the left side if (postActionbar == PostActionbarMode.RightHandShort) { @@ -688,24 +687,24 @@ fun PostFooterLine( } ActionBarButton( icon = - if (postView.saved) { - Icons.Filled.Bookmark - } else { - Icons.Outlined.BookmarkBorder - }, + if (postView.saved) { + Icons.Filled.Bookmark + } else { + Icons.Outlined.BookmarkBorder + }, contentDescription = - if (postView.saved) { - stringResource(R.string.removeBookmark) - } else { - stringResource(R.string.addBookmark) - }, + if (postView.saved) { + stringResource(R.string.removeBookmark) + } else { + stringResource(R.string.addBookmark) + }, onClick = { onSaveClick(postView) }, contentColor = - if (postView.saved) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.onBackground.muted - }, + if (postView.saved) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.onBackground.muted + }, account = account, ) ActionBarButton( @@ -714,10 +713,15 @@ fun PostFooterLine( account = account, onClick = { showMoreOptions = !showMoreOptions }, requiresAccount = false, - modifier = if (postActionbar == PostActionbarMode.LeftHandShort) Modifier.weight( - 1F, - true - ) else Modifier, + modifier = + if (postActionbar == PostActionbarMode.LeftHandShort) { + Modifier.weight( + 1F, + true, + ) + } else { + Modifier + }, ) if (postActionbar == PostActionbarMode.LeftHandShort) { @@ -866,7 +870,7 @@ fun PreviewPostListingCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, - instantScores = instantScores + instantScores = instantScores, ) } @@ -911,7 +915,7 @@ fun PreviewLinkPostListing() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, - instantScores = instantScores + instantScores = instantScores, ) } @@ -956,7 +960,7 @@ fun PreviewImagePostListingCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, - instantScores = instantScores + instantScores = instantScores, ) } @@ -1001,7 +1005,7 @@ fun PreviewImagePostListingSmallCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, - instantScores = instantScores + instantScores = instantScores, ) } @@ -1046,7 +1050,7 @@ fun PreviewLinkNoThumbnailPostListing() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, - instantScores = instantScores + instantScores = instantScores, ) } @@ -1084,7 +1088,7 @@ fun PostListing( showIfRead: Boolean, showScores: Boolean, postActionbarMode: Int, - instantScores: InstantScores + instantScores: InstantScores, ) { var viewSource by remember { mutableStateOf(false) } @@ -1202,9 +1206,9 @@ fun PostVotingTile( Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = - Modifier - .fillMaxHeight() - .padding(end = MEDIUM_PADDING), + Modifier + .fillMaxHeight() + .padding(end = MEDIUM_PADDING), ) { VoteGeneric( myVote = instantScores.myVote, @@ -1262,19 +1266,19 @@ fun PostListingList( ) { Column( modifier = - Modifier - .padding( - horizontal = MEDIUM_PADDING, - vertical = MEDIUM_PADDING, - ) - .testTag("jerboa:post"), + Modifier + .padding( + horizontal = MEDIUM_PADDING, + vertical = MEDIUM_PADDING, + ) + .testTag("jerboa:post"), ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = - Arrangement.spacedBy( - SMALL_PADDING, - ), + Arrangement.spacedBy( + SMALL_PADDING, + ), ) { if (showVotingArrowsInListView) { PostVotingTile( @@ -1288,9 +1292,9 @@ fun PostListingList( } Column( modifier = - Modifier - .weight(1f) - .clickable { onPostClick(postView) }, + Modifier + .weight(1f) + .clickable { onPostClick(postView) }, verticalArrangement = Arrangement.spacedBy(SMALL_PADDING), ) { PostName(postView = postView, showIfRead = showIfRead) @@ -1347,10 +1351,10 @@ fun PostListingList( } Text( text = - stringResource( - R.string.post_listing_comments_count, - postView.counts.comments, - ), + stringResource( + R.string.post_listing_comments_count, + postView.counts.comments, + ), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onBackground.muted, ) @@ -1438,14 +1442,14 @@ private fun ThumbnailTile( painter = painterResource(id = R.drawable.triangle), contentDescription = null, modifier = - Modifier - .size(THUMBNAIL_CARET_SIZE) - .align(Alignment.BottomEnd), + Modifier + .size(THUMBNAIL_CARET_SIZE) + .align(Alignment.BottomEnd), tint = - when (postType) { - PostType.Video -> MaterialTheme.jerboaColorScheme.videoHighlight - else -> MaterialTheme.jerboaColorScheme.imageHighlight - }, + when (postType) { + PostType.Video -> MaterialTheme.jerboaColorScheme.videoHighlight + else -> MaterialTheme.jerboaColorScheme.imageHighlight + }, ) } } @@ -1551,10 +1555,10 @@ fun PostListingCard( ) { Column( modifier = - Modifier - .padding(vertical = MEDIUM_PADDING) - .clickable { onPostClick(postView) } - .testTag("jerboa:post"), + Modifier + .padding(vertical = MEDIUM_PADDING) + .clickable { onPostClick(postView) } + .testTag("jerboa:post"), // see https://stackoverflow.com/questions/77010371/prevent-popup-from-adding-padding-in-a-column-with-arrangement-spacedbylarge-p // verticalArrangement = Arrangement.spacedBy(LARGE_PADDING), ) { @@ -1636,9 +1640,9 @@ fun MetadataCard(post: Post) { OutlinedCard( shape = MaterialTheme.shapes.medium, modifier = - Modifier - .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) - .fillMaxWidth(), + Modifier + .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) + .fillMaxWidth(), content = { Column( modifier = Modifier.padding(MEDIUM_PADDING), diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt index f6c97e507..74334a163 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt @@ -24,7 +24,6 @@ import androidx.compose.ui.unit.dp import com.jerboa.InstantScores import com.jerboa.JerboaAppState import com.jerboa.PostViewMode -import com.jerboa.feat.SwipeToActionType import com.jerboa.VoteType import com.jerboa.calculateNewInstantScores import com.jerboa.datatypes.PostFeatureData @@ -33,6 +32,7 @@ import com.jerboa.datatypes.samplePostView import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount import com.jerboa.feat.SwipeToActionPreset +import com.jerboa.feat.SwipeToActionType import com.jerboa.isScrolledToEnd import com.jerboa.rememberJerboaAppState import com.jerboa.ui.components.common.RetryLoadingPosts @@ -86,18 +86,18 @@ fun PostListings( showScores: Boolean, postActionbarMode: Int, showPostAppendRetry: Boolean, - swipeToActionPreset: Int + swipeToActionPreset: Int, ) { val leftActions = SwipeToActionPreset.entries[swipeToActionPreset].leftActions val rightActions = SwipeToActionPreset.entries[swipeToActionPreset].rightActions LazyColumn( state = listState, modifier = - Modifier - .padding(padding) - .fillMaxSize() - .simpleVerticalScrollbar(listState) - .testTag("jerboa:posts"), + Modifier + .padding(padding) + .fillMaxSize() + .simpleVerticalScrollbar(listState) + .testTag("jerboa:posts"), ) { item(contentType = "aboveContent") { contentAboveListings() @@ -118,38 +118,40 @@ fun PostListings( ), ) } - val swipeState = rememberSwipeActionState( - leftActions = leftActions, - rightActions = rightActions, - onAction = { action -> - when (action) { - SwipeToActionType.Upvote -> { - onUpvoteClick(postView) - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Upvote, - ) - } + val swipeState = + rememberSwipeActionState( + leftActions = leftActions, + rightActions = rightActions, + onAction = { action -> + when (action) { + SwipeToActionType.Upvote -> { + onUpvoteClick(postView) + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Upvote, + ) + } - SwipeToActionType.Downvote -> { - onDownvoteClick(postView) - instantScores.value = - calculateNewInstantScores( - instantScores.value, - voteType = VoteType.Downvote, - ) - } + SwipeToActionType.Downvote -> { + onDownvoteClick(postView) + instantScores.value = + calculateNewInstantScores( + instantScores.value, + voteType = VoteType.Downvote, + ) + } - SwipeToActionType.Save -> { - onSaveClick(postView) - } + SwipeToActionType.Save -> { + onSaveClick(postView) + } - SwipeToActionType.Reply -> { - onPostClick(postView) + SwipeToActionType.Reply -> { + onPostClick(postView) + } } - } - }) + }, + ) val content: @Composable RowScope.() -> Unit = { PostListing( @@ -197,7 +199,7 @@ fun PostListings( showIfRead = showIfRead, showScores = showScores, postActionbarMode = postActionbarMode, - instantScores = instantScores.value + instantScores = instantScores.value, ).let { if (!postView.read && markAsReadOnScroll) { DisposableEffect(key1 = postView.post.id) { @@ -214,7 +216,7 @@ fun PostListings( leftActions = leftActions, rightActions = rightActions, swipeableContent = content, - swipeState = swipeState + swipeState = swipeState, ) Divider(modifier = Modifier.padding(bottom = SMALL_PADDING)) } @@ -278,6 +280,6 @@ fun PreviewPostListings() { showScores = true, postActionbarMode = 0, showPostAppendRetry = false, - swipeToActionPreset = 0 + swipeToActionPreset = 0, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt b/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt index 391aa37b7..6b7728e7a 100644 --- a/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt @@ -136,7 +136,7 @@ fun LookAndFeelActivity( postActionbarMode = postActionbarMode.value, autoPlayGifs = autoPlayGifs.value, postNavigationGestureMode = postNavigationGestureModeState.value, - swipeToActionPreset = swipeToActionPreset.value + swipeToActionPreset = swipeToActionPreset.value, ), ) } @@ -149,9 +149,9 @@ fun LookAndFeelActivity( content = { padding -> Column( modifier = - Modifier - .verticalScroll(scrollState) - .padding(padding), + Modifier + .verticalScroll(scrollState) + .padding(padding), ) { SettingsListDropdown( title = { diff --git a/app/src/main/java/com/jerboa/ui/theme/Color.kt b/app/src/main/java/com/jerboa/ui/theme/Color.kt index 74e80c058..c9cb47dc0 100644 --- a/app/src/main/java/com/jerboa/ui/theme/Color.kt +++ b/app/src/main/java/com/jerboa/ui/theme/Color.kt @@ -453,7 +453,7 @@ fun crimson(): Pair { JerboaColorScheme( material = dark, imageHighlight = jerboa_image_highlight, - videoHighlight = jerboa_video_highlight + videoHighlight = jerboa_video_highlight, ) return Pair(jerboaLight, jerboaDark) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 901887695..91064c2e8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -415,7 +415,6 @@ Lock Post Unlock Post Type your reason - Swipe gesture presets Disabled Default (votes on right, share/reply on left) Left-right votes From b121bd305eec782249e72094f958863d1103fed0 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 23 Jan 2024 00:30:19 +0300 Subject: [PATCH 04/19] fix string resource --- app/src/main/res/values-ru/strings.xml | 4 ++-- app/src/main/res/values/strings.xml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 02880710e..8b5ff351a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -412,9 +412,9 @@ Заморозить пост Разморозить бост Введите причину - Преднастройки для смахивающего жеста + Преднастройка для смахивающего жеста Отключить - По умолчанию + С двух сторон Отриц. - слева, положит. - справа Только справа Только слева diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 91064c2e8..b710fc6c3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -416,7 +416,7 @@ Unlock Post Type your reason Disabled - Default (votes on right, share/reply on left) + Two sides Left-right votes Only right swipe Only left swipe @@ -424,4 +424,5 @@ Unfeature in Community Feature in Local Unfeature in Local + Preset for swipe gesture From fabdd5c288181f1e69ec459bace708dab930f691 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 23 Jan 2024 00:44:47 +0300 Subject: [PATCH 05/19] Do not use SwipeToAction when it is disabled --- .../ui/components/comment/CommentNode.kt | 20 +++++++++++------- .../ui/components/common/SwipeToAction.kt | 7 ++++++- .../jerboa/ui/components/post/PostListings.kt | 21 ++++++++++++------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index a19d19eb8..45b5546a5 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -297,7 +297,7 @@ fun LazyListScope.commentNodeItem( }, ) - val content: @Composable RowScope.() -> Unit = { + val swipeableContent: @Composable RowScope.() -> Unit = { AnimatedVisibility( visible = !isCollapsedByParent, enter = expandVertically(), @@ -425,12 +425,18 @@ fun LazyListScope.commentNodeItem( } } - SwipeToAction( - leftActions = leftActions, - rightActions = rightActions, - swipeableContent = content, - swipeState = swipeState, - ) + if (leftActions.size + rightActions.size > 0) { + SwipeToAction( + leftActions = leftActions, + rightActions = rightActions, + swipeableContent = swipeableContent, + swipeState = swipeState, + ) + } else { + Row { + swipeableContent() + } + } } increaseLazyListIndexTracker() diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index dcdf7bb90..b7afcfd68 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -103,7 +103,12 @@ fun SwipeToAction( .fillMaxHeight() .background(color = color) .align(if (swipeState.targetValue == DismissValue.DismissedToStart) Alignment.TopEnd else Alignment.TopStart), - contentAlignment = if (swipeState.targetValue == DismissValue.DismissedToStart) Alignment.CenterStart else Alignment.CenterEnd, + contentAlignment = + if (swipeState.targetValue == DismissValue.DismissedToStart) { + Alignment.CenterStart + } else { + Alignment.CenterEnd + }, ) { val tint = Color.White val modifier = diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt index 74334a163..57d5e9267 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt @@ -1,6 +1,7 @@ package com.jerboa.ui.components.post import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -153,7 +154,7 @@ fun PostListings( }, ) - val content: @Composable RowScope.() -> Unit = { + val swipeableContent: @Composable RowScope.() -> Unit = { PostListing( postView = postView, admins = admins, @@ -212,12 +213,18 @@ fun PostListings( } } } - SwipeToAction( - leftActions = leftActions, - rightActions = rightActions, - swipeableContent = content, - swipeState = swipeState, - ) + if (leftActions.size + rightActions.size > 0) { + SwipeToAction( + leftActions = leftActions, + rightActions = rightActions, + swipeableContent = swipeableContent, + swipeState = swipeState, + ) + } else { + Row { + swipeableContent() + } + } Divider(modifier = Modifier.padding(bottom = SMALL_PADDING)) } From 899171c781179814771d5de144f53f2df3af89e8 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 23 Jan 2024 01:08:03 +0300 Subject: [PATCH 06/19] Improve scrolling experience --- .../com/jerboa/feat/{SwipeToActionType.kt => SwipeToAction.kt} | 2 +- .../main/java/com/jerboa/ui/components/common/SwipeToAction.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename app/src/main/java/com/jerboa/feat/{SwipeToActionType.kt => SwipeToAction.kt} (98%) diff --git a/app/src/main/java/com/jerboa/feat/SwipeToActionType.kt b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt similarity index 98% rename from app/src/main/java/com/jerboa/feat/SwipeToActionType.kt rename to app/src/main/java/com/jerboa/feat/SwipeToAction.kt index f64712a1b..0a94256cc 100644 --- a/app/src/main/java/com/jerboa/feat/SwipeToActionType.kt +++ b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt @@ -21,7 +21,7 @@ enum class SwipeToActionType() { fun getActionToRangeList(actions: List): List, SwipeToActionType>> { val delta = if (actions.size > 2) 0.14f else 0.18f return actions.mapIndexed { index, it -> - (0.1f + delta * index) + (0.02f + delta * index) .rangeUntil(if (index == actions.size - 1) 1f else (0.1f + delta * (index + 1))) to it } } diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index b7afcfd68..f6684f7a6 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -149,7 +149,7 @@ fun rememberSwipeActionState( val progressState = remember { mutableFloatStateOf(1.0f) } val dismissState = rememberDismissState( - positionalThreshold = { 0f }, + positionalThreshold = { 48.dp.toPx() }, confirmValueChange = { dismissValue -> val action = when (dismissValue) { From 8a33f4138b9409cd17927baac05952aa65e4438b Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 23 Jan 2024 01:13:43 +0300 Subject: [PATCH 07/19] Increase color shift animation speed --- .../main/java/com/jerboa/ui/components/common/SwipeToAction.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index f6684f7a6..da7ad637c 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -83,7 +83,7 @@ fun SwipeToAction( haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) lastSwipeAction.value = currentAction?.second } - spring(stiffness = 1000f) + spring(stiffness = 1800f) }, label = "swipe color animation", targetValueByState = { state -> From 38388da16f6080b9748a4c4b48ce0b9571f65c8e Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 23 Jan 2024 01:54:49 +0300 Subject: [PATCH 08/19] Improve ranges --- app/src/main/java/com/jerboa/feat/SwipeToAction.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt index 0a94256cc..a8c5105e5 100644 --- a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt @@ -21,8 +21,8 @@ enum class SwipeToActionType() { fun getActionToRangeList(actions: List): List, SwipeToActionType>> { val delta = if (actions.size > 2) 0.14f else 0.18f return actions.mapIndexed { index, it -> - (0.02f + delta * index) - .rangeUntil(if (index == actions.size - 1) 1f else (0.1f + delta * (index + 1))) to it + (0.09f + delta * index) + .rangeUntil(if (index == actions.size - 1) 1f else (0.09f + delta * (index + 1))) to it } } From 30e807cac0ae72e0f99090f3fcecaae884831b85 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 23 Jan 2024 02:34:52 +0300 Subject: [PATCH 09/19] new preset: only votes --- app/src/main/java/com/jerboa/feat/SwipeToAction.kt | 5 +++++ app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 3 files changed, 7 insertions(+) diff --git a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt index a8c5105e5..b8d3b6a9f 100644 --- a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt @@ -92,4 +92,9 @@ enum class SwipeToActionPreset( emptyList(), R.string.only_left_swipe_action_preset, ), + ONLY_VOTES( + listOf(SwipeToActionType.Downvote), + listOf(SwipeToActionType.Upvote), + R.string.only_votes_swipe_action_preset, + ), } diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 8b5ff351a..615d54030 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -418,5 +418,6 @@ Отриц. - слева, положит. - справа Только справа Только слева + Только оценки \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b710fc6c3..15f9de13d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -425,4 +425,5 @@ Feature in Local Unfeature in Local Preset for swipe gesture + Only votes From ee9515e62701b2ff95c45733b22915ca95f38025 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Mon, 29 Jan 2024 23:15:35 +0300 Subject: [PATCH 10/19] fix deltas & rename resources --- app/src/main/java/com/jerboa/feat/SwipeToAction.kt | 10 +++++----- .../com/jerboa/ui/components/comment/CommentNode.kt | 4 ++-- .../com/jerboa/ui/components/comment/CommentNodes.kt | 5 +++-- .../ui/components/community/CommunityActivity.kt | 3 ++- .../jerboa/ui/components/home/BottomNavActivity.kt | 8 +++++--- .../com/jerboa/ui/components/home/HomeActivity.kt | 5 +++-- .../ui/components/person/PersonProfileActivity.kt | 5 +++-- .../com/jerboa/ui/components/post/PostActivity.kt | 2 +- .../com/jerboa/ui/components/post/PostListings.kt | 11 +++++++---- app/src/main/res/values-ru/strings.xml | 8 ++++---- app/src/main/res/values/strings.xml | 8 ++++---- 11 files changed, 39 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt index b8d3b6a9f..6e2326fb0 100644 --- a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt @@ -19,7 +19,7 @@ enum class SwipeToActionType() { companion object { fun getActionToRangeList(actions: List): List, SwipeToActionType>> { - val delta = if (actions.size > 2) 0.14f else 0.18f + val delta = if (actions.size > 2) 0.14f else 0.2f return actions.mapIndexed { index, it -> (0.09f + delta * index) .rangeUntil(if (index == actions.size - 1) 1f else (0.09f + delta * (index + 1))) to it @@ -61,16 +61,16 @@ enum class SwipeToActionPreset( val rightActions: List, val resId: Int, ) { - DISABLED(emptyList(), emptyList(), R.string.disabled_swipe_action_preset), + DISABLED(emptyList(), emptyList(), R.string.swipe_action_preset_disabled), DEFAULT( listOf(SwipeToActionType.Reply, SwipeToActionType.Save), listOf(SwipeToActionType.Upvote, SwipeToActionType.Downvote), - R.string.default_swipe_action_preset, + R.string.swipe_action_preset_default, ), LEFT_DOWNVOTE_RIGHT_UPVOTE( listOf(SwipeToActionType.Downvote, SwipeToActionType.Reply), listOf(SwipeToActionType.Upvote, SwipeToActionType.Save), - R.string.downvote_on_left_upvote_on_right_swipe_action_preset, + R.string.swipe_action_preset_downvote_on_left_upvote_on_right, ), ONLY_RIGHT( emptyList(), @@ -95,6 +95,6 @@ enum class SwipeToActionPreset( ONLY_VOTES( listOf(SwipeToActionType.Downvote), listOf(SwipeToActionType.Upvote), - R.string.only_votes_swipe_action_preset, + R.string.swipe_action_preset_only_votes, ), } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index 45b5546a5..1675a1e2d 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -216,7 +216,7 @@ fun LazyListScope.commentNodeItem( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, ) { val commentView = node.commentView val commentId = commentView.comment.id @@ -528,7 +528,7 @@ fun LazyListScope.missingCommentNodeItem( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, ) { val commentId = node.missingCommentView.commentId diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt index 06206470a..c3c2bddf2 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt @@ -12,6 +12,7 @@ import com.jerboa.CommentNode import com.jerboa.CommentNodeData import com.jerboa.MissingCommentNode import com.jerboa.db.entity.Account +import com.jerboa.feat.SwipeToActionPreset import it.vercruysse.lemmyapi.v0x19.datatypes.CommentView import it.vercruysse.lemmyapi.v0x19.datatypes.Community import it.vercruysse.lemmyapi.v0x19.datatypes.CommunityModeratorView @@ -58,7 +59,7 @@ fun CommentNodes( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, ) { LazyColumn(state = listState) { commentNodeItems( @@ -143,7 +144,7 @@ fun LazyListScope.commentNodeItems( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, ) { nodes.forEach { node -> when (node) { diff --git a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt index 2f0334642..df0e6fa15 100644 --- a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt @@ -35,6 +35,7 @@ import com.jerboa.VoteType import com.jerboa.api.ApiState import com.jerboa.db.entity.isAnon import com.jerboa.feat.BlurTypes +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.feat.doIfReadyElseDisplayInfo import com.jerboa.feat.shareLink import com.jerboa.hostName @@ -85,7 +86,7 @@ fun CommunityActivity( showPostLinkPreviews: Boolean, markAsReadOnScroll: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, ) { Log.d("jerboa", "got to community activity") diff --git a/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt index 2705a049c..11660fdb8 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt @@ -42,11 +42,13 @@ import arrow.core.Either import com.jerboa.JerboaAppState import com.jerboa.R import com.jerboa.db.entity.AppSettings +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.feat.doIfReadyElseDisplayInfo import com.jerboa.model.AccountViewModel import com.jerboa.model.AppSettingsViewModel import com.jerboa.model.HomeViewModel import com.jerboa.model.SiteViewModel +import com.jerboa.toEnum import com.jerboa.ui.components.common.BottomAppBarAll import com.jerboa.ui.components.common.JerboaSnackbarHost import com.jerboa.ui.components.common.getCurrentAccount @@ -216,7 +218,7 @@ fun BottomNavActivity( showPostLinkPreviews = appSettings.showPostLinkPreviews, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset, + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum(), ) } @@ -256,7 +258,7 @@ fun BottomNavActivity( drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset, + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum(), ) } @@ -276,7 +278,7 @@ fun BottomNavActivity( drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset, + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum(), ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt index 37d4b4a8a..abdd0135d 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt @@ -42,6 +42,7 @@ import com.jerboa.api.ApiState import com.jerboa.db.entity.Account import com.jerboa.db.entity.isAnon import com.jerboa.db.entity.isReady +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.feat.doIfReadyElseDisplayInfo import com.jerboa.model.AccountViewModel import com.jerboa.model.AppSettingsViewModel @@ -91,7 +92,7 @@ fun HomeActivity( showPostLinkPreviews: Boolean, markAsReadOnScroll: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, ) { Log.d("jerboa", "got to home activity") @@ -205,7 +206,7 @@ fun MainPostListingsContent( snackbarHostState: SnackbarHostState, markAsReadOnScroll: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, ) { val ctx = LocalContext.current val scope = rememberCoroutineScope() diff --git a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt index 209b7bbdd..3cead522d 100644 --- a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt @@ -52,6 +52,7 @@ import com.jerboa.datatypes.getDisplayName import com.jerboa.datatypes.getLocalizedStringForUserTab import com.jerboa.db.entity.Account import com.jerboa.db.entity.isAnon +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.feat.doIfReadyElseDisplayInfo import com.jerboa.isScrolledToEnd import com.jerboa.model.AccountViewModel @@ -118,7 +119,7 @@ fun PersonProfileActivity( drawerState: DrawerState, markAsReadOnScroll: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, onBack: (() -> Unit)? = null, ) { Log.d("jerboa", "got to person activity") @@ -304,7 +305,7 @@ fun UserTabs( snackbarHostState: SnackbarHostState, showScores: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, ) { val tabTitles = if (savedMode) { diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt index fc79b8b45..91aa6c5e6 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt @@ -133,7 +133,7 @@ fun PostActivity( blurNSFW: Int, showPostLinkPreview: Boolean, postActionbarMode: Int, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, ) { Log.d("jerboa", "got to post activity") diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt index 57d5e9267..f76b49688 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt @@ -16,8 +16,10 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview @@ -87,10 +89,10 @@ fun PostListings( showScores: Boolean, postActionbarMode: Int, showPostAppendRetry: Boolean, - swipeToActionPreset: Int, + swipeToActionPreset: SwipeToActionPreset, ) { - val leftActions = SwipeToActionPreset.entries[swipeToActionPreset].leftActions - val rightActions = SwipeToActionPreset.entries[swipeToActionPreset].rightActions + val leftActions = swipeToActionPreset.leftActions + val rightActions = swipeToActionPreset.rightActions LazyColumn( state = listState, modifier = @@ -108,6 +110,7 @@ fun PostListings( items = posts, contentType = { _, _ -> "Post" }, ) { index, postView -> + val myVote by remember { mutableStateOf(null) } val instantScores = remember { mutableStateOf( @@ -287,6 +290,6 @@ fun PreviewPostListings() { showScores = true, postActionbarMode = 0, showPostAppendRetry = false, - swipeToActionPreset = 0, + swipeToActionPreset = SwipeToActionPreset.DISABLED, ) } diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 615d54030..15a70cbd1 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -413,11 +413,11 @@ Разморозить бост Введите причину Преднастройка для смахивающего жеста - Отключить - С двух сторон - Отриц. - слева, положит. - справа + Отключить + С двух сторон + Отриц. - слева, положит. - справа Только справа Только слева - Только оценки + Только оценки \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 15f9de13d..c78b5b8a2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -415,9 +415,9 @@ Lock Post Unlock Post Type your reason - Disabled - Two sides - Left-right votes + Disabled + Two sides + Left-right votes Only right swipe Only left swipe Feature in Community @@ -425,5 +425,5 @@ Feature in Local Unfeature in Local Preset for swipe gesture - Only votes + Only votes From 04444773d2b6ed30a1446211d3a164f91992997a Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 30 Jan 2024 01:32:36 +0300 Subject: [PATCH 11/19] SwipeToAction implemented correctly, SwipeToDismiss replaced with SwipeToDismissBox, fixed swipe ranges --- app/src/main/java/com/jerboa/MainActivity.kt | 6 +- .../java/com/jerboa/feat/SwipeToAction.kt | 12 +- .../ui/components/comment/CommentNode.kt | 41 ++- .../ui/components/comment/CommentNodes.kt | 6 + .../ui/components/common/SwipeToAction.kt | 24 +- .../components/community/CommunityActivity.kt | 3 +- .../ui/components/home/BottomNavActivity.kt | 4 +- .../jerboa/ui/components/home/HomeActivity.kt | 3 +- .../person/PersonProfileActivity.kt | 6 + .../jerboa/ui/components/post/PostActivity.kt | 4 + .../jerboa/ui/components/post/PostListing.kt | 288 ++++++++++-------- .../jerboa/ui/components/post/PostListings.kt | 5 + .../components/settings/SettingsActivity.kt | 1 + .../lookandfeel/LookAndFeelActivity.kt | 29 +- 14 files changed, 270 insertions(+), 162 deletions(-) diff --git a/app/src/main/java/com/jerboa/MainActivity.kt b/app/src/main/java/com/jerboa/MainActivity.kt index 5757933e8..18a216399 100644 --- a/app/src/main/java/com/jerboa/MainActivity.kt +++ b/app/src/main/java/com/jerboa/MainActivity.kt @@ -319,7 +319,8 @@ class MainActivity : AppCompatActivity() { drawerState = drawerState, onBack = appState::popBackStack, markAsReadOnScroll = appSettings.markAsReadOnScroll, - postActionbarMode = appSettings.postActionbarMode + postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() ) } @@ -357,6 +358,7 @@ class MainActivity : AppCompatActivity() { drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() ) } @@ -468,6 +470,7 @@ class MainActivity : AppCompatActivity() { blurNSFW = appSettings.blurNSFW, showPostLinkPreview = appSettings.showPostLinkPreviews, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() ) } } @@ -501,6 +504,7 @@ class MainActivity : AppCompatActivity() { blurNSFW = appSettings.blurNSFW, showPostLinkPreview = appSettings.showPostLinkPreviews, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() ) } diff --git a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt index 6e2326fb0..25bf616e2 100644 --- a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt @@ -7,10 +7,12 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.unit.dp import com.jerboa.R -enum class SwipeToActionType() { +enum class SwipeToActionType { Upvote, Downvote, Reply, @@ -18,11 +20,15 @@ enum class SwipeToActionType() { ; companion object { + + const val START_THRESHOLD = 0.05f + fun getActionToRangeList(actions: List): List, SwipeToActionType>> { + val start = START_THRESHOLD + 0.05f val delta = if (actions.size > 2) 0.14f else 0.2f return actions.mapIndexed { index, it -> - (0.09f + delta * index) - .rangeUntil(if (index == actions.size - 1) 1f else (0.09f + delta * (index + 1))) to it + (start + delta * index) + .rangeUntil(if (index == actions.size - 1) 1f else (start + delta * (index + 1))) to it } } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index 90b8066f0..9ecd939b0 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -60,6 +60,7 @@ import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount import com.jerboa.feat.InstantScores import com.jerboa.feat.SwipeToActionPreset +import com.jerboa.feat.SwipeToActionType import com.jerboa.feat.VoteType import com.jerboa.feat.canMod import com.jerboa.isPostCreator @@ -69,6 +70,7 @@ import com.jerboa.ui.components.common.MarkdownHelper import com.jerboa.ui.components.common.MyMarkdownText import com.jerboa.ui.components.common.SwipeToAction import com.jerboa.ui.components.common.VoteGeneric +import com.jerboa.ui.components.common.rememberSwipeActionState import com.jerboa.ui.components.community.CommunityLink import com.jerboa.ui.theme.LARGE_PADDING import com.jerboa.ui.theme.MEDIUM_PADDING @@ -259,6 +261,27 @@ fun LazyListScope.commentNodeItem( ) } + val swipeState = rememberSwipeActionState(swipeToActionPreset) { + when(it) { + SwipeToActionType.Upvote -> { + instantScores = + instantScores.update(VoteType.Upvote) + onUpvoteClick(commentView) + } + SwipeToActionType.Downvote -> { + instantScores = + instantScores.update(VoteType.Downvote) + onDownvoteClick(commentView) + } + SwipeToActionType.Reply -> { + onReplyClick(commentView) + } + SwipeToActionType.Save -> { + onSaveClick(commentView) + } + } + } + val swipeableContent: @Composable RowScope.() -> Unit = { AnimatedVisibility( visible = !isCollapsedByParent, @@ -383,8 +406,16 @@ fun LazyListScope.commentNodeItem( } } - Row { - swipeableContent() + if(swipeToActionPreset != SwipeToActionPreset.DISABLED) { + SwipeToAction( + swipeToActionPreset = swipeToActionPreset, + swipeableContent = swipeableContent, + swipeState = swipeState + ) + } else { + Row { + swipeableContent() + } } @@ -440,6 +471,7 @@ fun LazyListScope.commentNodeItem( showScores = showScores, admins = admins, moderators = moderators, + swipeToActionPreset = swipeToActionPreset ) } @@ -482,6 +514,7 @@ fun LazyListScope.missingCommentNodeItem( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, + swipeToActionPreset: SwipeToActionPreset ) { val commentId = node.missingCommentView.commentId @@ -586,6 +619,7 @@ fun LazyListScope.missingCommentNodeItem( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, + swipeToActionPreset = swipeToActionPreset ) } @@ -863,7 +897,8 @@ fun CommentNodesPreview() { showAvatar = true, blurNSFW = 1, account = AnonAccount, - showScores = true + showScores = true, + swipeToActionPreset = SwipeToActionPreset.DEFAULT ) } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt index e04883245..187d95a13 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt @@ -13,6 +13,7 @@ import com.jerboa.CommentNodeData import com.jerboa.MissingCommentNode import com.jerboa.datatypes.BanFromCommunityData import com.jerboa.db.entity.Account +import com.jerboa.feat.SwipeToActionPreset import it.vercruysse.lemmyapi.v0x19.datatypes.CommentId import it.vercruysse.lemmyapi.v0x19.datatypes.CommentView import it.vercruysse.lemmyapi.v0x19.datatypes.Community @@ -64,6 +65,7 @@ fun CommentNodes( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, + swipeToActionPreset: SwipeToActionPreset ) { LazyColumn(state = listState) { commentNodeItems( @@ -105,6 +107,7 @@ fun CommentNodes( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, + swipeToActionPreset = swipeToActionPreset ) item { Spacer(modifier = Modifier.height(100.dp)) @@ -151,6 +154,7 @@ fun LazyListScope.commentNodeItems( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, + swipeToActionPreset: SwipeToActionPreset ) { nodes.forEach { node -> when (node) { @@ -194,6 +198,7 @@ fun LazyListScope.commentNodeItems( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, + swipeToActionPreset = swipeToActionPreset ) is MissingCommentNode -> @@ -236,6 +241,7 @@ fun LazyListScope.commentNodeItems( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, + swipeToActionPreset = swipeToActionPreset ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index 492d4766d..375c4dcee 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.requiredWidth import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon -import androidx.compose.material3.SwipeToDismiss import androidx.compose.material3.SwipeToDismissBox import androidx.compose.material3.SwipeToDismissBoxState import androidx.compose.material3.SwipeToDismissBoxValue @@ -29,22 +28,23 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.unit.dp +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.feat.SwipeToActionType +import com.jerboa.feat.SwipeToActionType.Companion.START_THRESHOLD @Composable @ExperimentalMaterial3Api fun SwipeToAction( - leftActions: List, - rightActions: List, + swipeToActionPreset: SwipeToActionPreset, swipeableContent: @Composable RowScope.() -> Unit, swipeState: SwipeToDismissBoxState, ) { val haptic = LocalHapticFeedback.current val leftActionsRanges = - remember(leftActions) { SwipeToActionType.getActionToRangeList(leftActions) } + remember (swipeToActionPreset) {SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions)} val rightActionsRanges = - remember(rightActions) { SwipeToActionType.getActionToRangeList(rightActions) } + remember (swipeToActionPreset) {SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions)} fun actionByState(state: SwipeToDismissBoxState): Pair, SwipeToActionType>? { return when (state.targetValue) { @@ -64,8 +64,8 @@ fun SwipeToAction( remember(swipeState.progress, swipeState.targetValue) { actionByState(swipeState) } SwipeToDismissBox( - enableDismissFromStartToEnd = leftActions.isNotEmpty(), - enableDismissFromEndToStart = rightActions.isNotEmpty(), + enableDismissFromStartToEnd = leftActionsRanges.isNotEmpty(), + enableDismissFromEndToStart = rightActionsRanges.isNotEmpty(), state = swipeState, backgroundContent = { val lastSwipeAction = remember { mutableStateOf(null) } @@ -97,7 +97,7 @@ fun SwipeToAction( .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) .fillMaxHeight() .background(color = color) - .align(if (swipeState.targetValue == SwipeToDismissBoxValue.StartToEnd) Alignment.TopEnd else Alignment.TopStart), + .align(if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) Alignment.TopEnd else Alignment.TopStart), contentAlignment = if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) { Alignment.CenterStart @@ -130,8 +130,7 @@ fun SwipeToAction( @OptIn(ExperimentalMaterial3Api::class) @Composable fun rememberSwipeActionState( - leftActions: List, - rightActions: List, + swipeToActionPreset: SwipeToActionPreset, onAction: (action: SwipeToActionType) -> Unit, ): SwipeToDismissBoxState { /* @@ -139,12 +138,13 @@ fun rememberSwipeActionState( They didn't fix it with new SwipeToDismissBoxState */ val leftActionsRanges = - remember(leftActions) { SwipeToActionType.getActionToRangeList(leftActions) } + remember(swipeToActionPreset) {SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions)} val rightActionsRanges = - remember(rightActions) { SwipeToActionType.getActionToRangeList(rightActions) } + remember(swipeToActionPreset) {SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions)} val progressState = remember { mutableFloatStateOf(1.0f) } val dismissState = rememberSwipeToDismissBoxState( + positionalThreshold = { totalDistance -> totalDistance * START_THRESHOLD }, confirmValueChange = { dismissValue -> val action = when (dismissValue) { diff --git a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt index 570e1d945..6942d6ed4 100644 --- a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt @@ -420,7 +420,8 @@ fun CommunityActivity( showIfRead = true, showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, - showPostAppendRetry = communityViewModel.postsRes is ApiState.AppendingFailure + showPostAppendRetry = communityViewModel.postsRes is ApiState.AppendingFailure, + swipeToActionPreset = swipeToActionPreset ) } diff --git a/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt index 890db1671..859c0ad6a 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt @@ -257,7 +257,8 @@ fun BottomNavActivity( showPostLinkPreviews = appSettings.showPostLinkPreviews, drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, - postActionbarMode = appSettings.postActionbarMode + postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() ) } @@ -277,6 +278,7 @@ fun BottomNavActivity( drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt index 2201a033b..c111a5bdb 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt @@ -421,7 +421,8 @@ fun MainPostListingsContent( showIfRead = true, showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, - showPostAppendRetry = homeViewModel.postsRes is ApiState.AppendingFailure + showPostAppendRetry = homeViewModel.postsRes is ApiState.AppendingFailure, + swipeToActionPreset = swipeToActionPreset ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt index ee9ce0419..1a6a826e5 100644 --- a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt @@ -51,6 +51,7 @@ import com.jerboa.datatypes.getDisplayName import com.jerboa.datatypes.getLocalizedStringForUserTab import com.jerboa.db.entity.Account import com.jerboa.db.entity.isAnon +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.feat.VoteType import com.jerboa.feat.doIfReadyElseDisplayInfo import com.jerboa.feat.newVote @@ -122,6 +123,7 @@ fun PersonProfileActivity( markAsReadOnScroll: Boolean, postActionbarMode: Int, onBack: (() -> Unit)? = null, + swipeToActionPreset: SwipeToActionPreset ) { Log.d("jerboa", "got to person activity") @@ -272,6 +274,7 @@ fun PersonProfileActivity( snackbarHostState = snackbarHostState, showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, + swipeToActionPreset = swipeToActionPreset ) }, ) @@ -307,6 +310,7 @@ fun UserTabs( snackbarHostState: SnackbarHostState, showScores: Boolean, postActionbarMode: Int, + swipeToActionPreset: SwipeToActionPreset ) { val tabTitles = if (savedMode) { @@ -618,6 +622,7 @@ fun UserTabs( showScores = showScores, postActionbarMode = postActionbarMode, showPostAppendRetry = personProfileViewModel.personDetailsRes is ApiState.AppendingFailure, + swipeToActionPreset = swipeToActionPreset ) } else -> {} @@ -838,6 +843,7 @@ fun UserTabs( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, + swipeToActionPreset = swipeToActionPreset ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt index f097d2e66..30c96e082 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt @@ -59,6 +59,7 @@ import com.jerboa.buildCommentsTree import com.jerboa.datatypes.BanFromCommunityData import com.jerboa.datatypes.getLocalizedCommentSortTypeName import com.jerboa.db.entity.isAnon +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.feat.VoteType import com.jerboa.feat.doIfReadyElseDisplayInfo import com.jerboa.feat.newVote @@ -134,6 +135,7 @@ fun PostActivity( blurNSFW: Int, showPostLinkPreview: Boolean, postActionbarMode: Int, + swipeToActionPreset: SwipeToActionPreset ) { Log.d("jerboa", "got to post activity") @@ -461,6 +463,7 @@ fun PostActivity( showIfRead = false, showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, + swipeToActionPreset = swipeToActionPreset ) } @@ -690,6 +693,7 @@ fun PostActivity( }, blurNSFW = blurNSFW, showScores = siteViewModel.showScores(), + swipeToActionPreset = swipeToActionPreset ) item { Spacer(modifier = Modifier.height(100.dp)) diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt index 79bcbb24c..15f347a58 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize @@ -72,6 +73,8 @@ import com.jerboa.db.entity.AnonAccount import com.jerboa.feat.BlurTypes import com.jerboa.feat.InstantScores import com.jerboa.feat.PostActionbarMode +import com.jerboa.feat.SwipeToActionPreset +import com.jerboa.feat.SwipeToActionType import com.jerboa.feat.VoteType import com.jerboa.feat.amAdmin import com.jerboa.feat.amMod @@ -97,8 +100,10 @@ import com.jerboa.ui.components.common.PictrsThumbnailImage import com.jerboa.ui.components.common.PictrsUrlImage import com.jerboa.ui.components.common.ScoreAndTime import com.jerboa.ui.components.common.SimpleTopAppBar +import com.jerboa.ui.components.common.SwipeToAction import com.jerboa.ui.components.common.TimeAgo import com.jerboa.ui.components.common.VoteGeneric +import com.jerboa.ui.components.common.rememberSwipeActionState import com.jerboa.ui.components.common.scoreColor import com.jerboa.ui.components.community.CommunityLink import com.jerboa.ui.components.community.CommunityName @@ -865,6 +870,7 @@ fun PreviewPostListingCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, + swipeToActionPreset = SwipeToActionPreset.DEFAULT ) } @@ -904,6 +910,7 @@ fun PreviewLinkPostListing() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, + swipeToActionPreset = SwipeToActionPreset.DEFAULT ) } @@ -943,6 +950,7 @@ fun PreviewImagePostListingCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, + swipeToActionPreset = SwipeToActionPreset.DEFAULT ) } @@ -982,6 +990,7 @@ fun PreviewImagePostListingSmallCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, + swipeToActionPreset = SwipeToActionPreset.DEFAULT ) } @@ -1021,9 +1030,11 @@ fun PreviewLinkNoThumbnailPostListing() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, + swipeToActionPreset = SwipeToActionPreset.DEFAULT ) } +@OptIn(ExperimentalMaterial3Api::class) @Composable fun PostListing( postView: PostView, @@ -1060,6 +1071,7 @@ fun PostListing( showIfRead: Boolean, showScores: Boolean, postActionbarMode: Int, + swipeToActionPreset: SwipeToActionPreset ) { // This stores vote data var instantScores by @@ -1076,128 +1088,166 @@ fun PostListing( var viewSource by remember { mutableStateOf(false) } - when (postViewMode) { - PostViewMode.Card -> - PostListingCard( - postView = postView, - admins = admins, - moderators = moderators, - instantScores = instantScores, - onUpvoteClick = { - instantScores = instantScores.update(VoteType.Upvote) - onUpvoteClick(postView) - }, - onDownvoteClick = { - instantScores = instantScores.update(VoteType.Downvote) - onDownvoteClick(postView) - }, - onReplyClick = onReplyClick, - onPostClick = onPostClick, - onSaveClick = onSaveClick, - onCommunityClick = onCommunityClick, - onEditPostClick = onEditPostClick, - onDeletePostClick = onDeletePostClick, - onReportClick = onReportClick, - onRemoveClick = onRemoveClick, - onBanPersonClick = onBanPersonClick, - onBanFromCommunityClick = onBanFromCommunityClick, - onLockPostClick = onLockPostClick, - onFeaturePostClick = onFeaturePostClick, - onPersonClick = onPersonClick, - onViewSourceClick = { - viewSource = !viewSource - }, - viewSource = viewSource, - showReply = showReply, - showCommunityName = showCommunityName, - fullBody = fullBody, - account = account, - expandedImage = true, - enableDownVotes = enableDownVotes, - showAvatar = showAvatar, - useCustomTabs = useCustomTabs, - usePrivateTabs = usePrivateTabs, - blurNSFW = blurNSFW, - showPostLinkPreview = showPostLinkPreview, - appState = appState, - showIfRead = showIfRead, - showScores = showScores, - postActionbarMode = postActionbarMode, - ) + val swipeState = rememberSwipeActionState(swipeToActionPreset) { + when(it) { + SwipeToActionType.Upvote -> { + instantScores = + instantScores.update(VoteType.Upvote) + onUpvoteClick(postView) + } + SwipeToActionType.Downvote -> { + instantScores = + instantScores.update(VoteType.Downvote) + onDownvoteClick(postView) + } + SwipeToActionType.Reply -> { + onReplyClick(postView) + } + SwipeToActionType.Save -> { + onSaveClick(postView) + } + } + } - PostViewMode.SmallCard -> - PostListingCard( - postView = postView, - admins = admins, - moderators = moderators, - instantScores = instantScores, - onUpvoteClick = { - instantScores = instantScores.update(VoteType.Upvote) - onUpvoteClick(postView) - }, - onDownvoteClick = { - instantScores = instantScores.update(VoteType.Downvote) - onDownvoteClick(postView) - }, - onReplyClick = onReplyClick, - onPostClick = onPostClick, - onSaveClick = onSaveClick, - onCommunityClick = onCommunityClick, - onEditPostClick = onEditPostClick, - onDeletePostClick = onDeletePostClick, - onReportClick = onReportClick, - onRemoveClick = onRemoveClick, - onBanPersonClick = onBanPersonClick, - onBanFromCommunityClick = onBanFromCommunityClick, - onLockPostClick = onLockPostClick, - onFeaturePostClick = onFeaturePostClick, - onPersonClick = onPersonClick, - onViewSourceClick = { - viewSource = !viewSource - }, - viewSource = viewSource, - showReply = showReply, - showCommunityName = showCommunityName, - fullBody = false, - account = account, - expandedImage = false, - enableDownVotes = enableDownVotes, - showAvatar = showAvatar, - useCustomTabs = useCustomTabs, - usePrivateTabs = usePrivateTabs, - blurNSFW = blurNSFW, - showPostLinkPreview = showPostLinkPreview, - appState = appState, - showScores = showScores, - postActionbarMode = postActionbarMode, - ) + val swipeableContent: @Composable RowScope.() -> Unit = { + Row { + when (postViewMode) { + PostViewMode.Card -> + PostListingCard( + postView = postView, + admins = admins, + moderators = moderators, + instantScores = instantScores, + onUpvoteClick = { + instantScores = instantScores.update(VoteType.Upvote) + onUpvoteClick(postView) + }, + onDownvoteClick = { + instantScores = instantScores.update(VoteType.Downvote) + onDownvoteClick(postView) + }, + onReplyClick = onReplyClick, + onPostClick = onPostClick, + onSaveClick = onSaveClick, + onCommunityClick = onCommunityClick, + onEditPostClick = onEditPostClick, + onDeletePostClick = onDeletePostClick, + onReportClick = onReportClick, + onRemoveClick = onRemoveClick, + onBanPersonClick = onBanPersonClick, + onBanFromCommunityClick = onBanFromCommunityClick, + onLockPostClick = onLockPostClick, + onFeaturePostClick = onFeaturePostClick, + onPersonClick = onPersonClick, + onViewSourceClick = { + viewSource = !viewSource + }, + viewSource = viewSource, + showReply = showReply, + showCommunityName = showCommunityName, + fullBody = fullBody, + account = account, + expandedImage = true, + enableDownVotes = enableDownVotes, + showAvatar = showAvatar, + useCustomTabs = useCustomTabs, + usePrivateTabs = usePrivateTabs, + blurNSFW = blurNSFW, + showPostLinkPreview = showPostLinkPreview, + appState = appState, + showIfRead = showIfRead, + showScores = showScores, + postActionbarMode = postActionbarMode, + ) - PostViewMode.List -> - PostListingList( - postView = postView, - instantScores = instantScores, - onUpvoteClick = { - instantScores = instantScores.update(VoteType.Upvote) - onUpvoteClick(postView) - }, - onDownvoteClick = { - instantScores = instantScores.update(VoteType.Downvote) - onDownvoteClick(postView) - }, - onPostClick = onPostClick, - showCommunityName = showCommunityName, - account = account, - showVotingArrowsInListView = showVotingArrowsInListView, - showAvatar = showAvatar, - useCustomTabs = useCustomTabs, - usePrivateTabs = usePrivateTabs, - blurNSFW = blurNSFW, - appState = appState, - showIfRead = showIfRead, - enableDownVotes = enableDownVotes, - showScores = showScores, - ) + PostViewMode.SmallCard -> + PostListingCard( + postView = postView, + admins = admins, + moderators = moderators, + instantScores = instantScores, + onUpvoteClick = { + instantScores = instantScores.update(VoteType.Upvote) + onUpvoteClick(postView) + }, + onDownvoteClick = { + instantScores = instantScores.update(VoteType.Downvote) + onDownvoteClick(postView) + }, + onReplyClick = onReplyClick, + onPostClick = onPostClick, + onSaveClick = onSaveClick, + onCommunityClick = onCommunityClick, + onEditPostClick = onEditPostClick, + onDeletePostClick = onDeletePostClick, + onReportClick = onReportClick, + onRemoveClick = onRemoveClick, + onBanPersonClick = onBanPersonClick, + onBanFromCommunityClick = onBanFromCommunityClick, + onLockPostClick = onLockPostClick, + onFeaturePostClick = onFeaturePostClick, + onPersonClick = onPersonClick, + onViewSourceClick = { + viewSource = !viewSource + }, + viewSource = viewSource, + showReply = showReply, + showCommunityName = showCommunityName, + fullBody = false, + account = account, + expandedImage = false, + enableDownVotes = enableDownVotes, + showAvatar = showAvatar, + useCustomTabs = useCustomTabs, + usePrivateTabs = usePrivateTabs, + blurNSFW = blurNSFW, + showPostLinkPreview = showPostLinkPreview, + appState = appState, + showScores = showScores, + postActionbarMode = postActionbarMode, + ) + + PostViewMode.List -> + PostListingList( + postView = postView, + instantScores = instantScores, + onUpvoteClick = { + instantScores = instantScores.update(VoteType.Upvote) + onUpvoteClick(postView) + }, + onDownvoteClick = { + instantScores = instantScores.update(VoteType.Downvote) + onDownvoteClick(postView) + }, + onPostClick = onPostClick, + showCommunityName = showCommunityName, + account = account, + showVotingArrowsInListView = showVotingArrowsInListView, + showAvatar = showAvatar, + useCustomTabs = useCustomTabs, + usePrivateTabs = usePrivateTabs, + blurNSFW = blurNSFW, + appState = appState, + showIfRead = showIfRead, + enableDownVotes = enableDownVotes, + showScores = showScores, + ) + } + } } + + if(swipeToActionPreset != SwipeToActionPreset.DISABLED) { + SwipeToAction( + swipeToActionPreset = swipeToActionPreset, + swipeableContent = swipeableContent, + swipeState = swipeState + ) + } else { + Row { + swipeableContent() + } + } + } @Composable diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt index 597c2b420..3aef918cf 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt @@ -1,6 +1,7 @@ package com.jerboa.ui.components.post import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -26,6 +27,7 @@ import com.jerboa.datatypes.sampleLinkPostView import com.jerboa.datatypes.samplePostView import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.isScrolledToEnd import com.jerboa.rememberJerboaAppState import com.jerboa.ui.components.common.RetryLoadingPosts @@ -80,6 +82,7 @@ fun PostListings( showScores: Boolean, postActionbarMode: Int, showPostAppendRetry: Boolean, + swipeToActionPreset: SwipeToActionPreset ) { LazyColumn( state = listState, @@ -131,6 +134,7 @@ fun PostListings( showIfRead = showIfRead, showScores = showScores, postActionbarMode = postActionbarMode, + swipeToActionPreset = swipeToActionPreset ).let { if (!postView.read && markAsReadOnScroll) { DisposableEffect(key1 = postView.post.id) { @@ -206,5 +210,6 @@ fun PreviewPostListings() { showScores = true, postActionbarMode = 0, showPostAppendRetry = false, + swipeToActionPreset = SwipeToActionPreset.DEFAULT ) } diff --git a/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt b/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt index 01c3407b7..728cd00ca 100644 --- a/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt @@ -47,6 +47,7 @@ fun SettingsActivity( content = { padding -> Column(modifier = Modifier.padding(padding)) { SettingsMenuLink( + title = { Text(stringResource(R.string.settings_activity_look_and_feel)) }, icon = { Icon( diff --git a/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt b/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt index 0bf6646e3..b52d59633 100644 --- a/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt @@ -45,7 +45,6 @@ import com.jerboa.feat.BackConfirmationMode import com.jerboa.feat.BlurTypes import com.jerboa.feat.PostActionbarMode import com.jerboa.feat.PostNavigationGestureMode -import com.jerboa.feat.SwipeToActionPreset import com.jerboa.getLangPreferenceDropdownEntries import com.jerboa.matchLocale import com.jerboa.model.AppSettingsViewModel @@ -149,9 +148,9 @@ fun LookAndFeelActivity( content = { padding -> Column( modifier = - Modifier - .verticalScroll(scrollState) - .padding(padding), + Modifier + .verticalScroll(scrollState) + .padding(padding), ) { SettingsListDropdown( title = { @@ -184,10 +183,10 @@ fun LookAndFeelActivity( title = { Text( text = - stringResource( - R.string.look_and_feel_font_size, - fontSizeState.value.toInt(), - ), + stringResource( + R.string.look_and_feel_font_size, + fontSizeState.value.toInt(), + ), ) }, onValueChangeFinished = { updateAppSettings() }, @@ -306,18 +305,6 @@ fun LookAndFeelActivity( items = BlurTypes.entries.map { stringResource(it.resId) }, onItemSelected = { _, _ -> updateAppSettings() }, ) - SettingsListDropdown( - state = swipeToActionPreset, - icon = { - Icon( - imageVector = Icons.Outlined.Swipe, - contentDescription = null, - ) - }, - title = { Text(stringResource(id = R.string.swipe_to_action_presets)) }, - items = SwipeToActionPreset.entries.map { stringResource(it.resId) }, - onItemSelected = { _, _ -> updateAppSettings() }, - ) SettingsCheckbox( state = showBottomNavState, title = { @@ -413,4 +400,4 @@ fun LookAndFeelActivity( } }, ) -} +} \ No newline at end of file From 45ea9e28c01fdd7144c8f43a898131e8c1ef5210 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 30 Jan 2024 01:36:28 +0300 Subject: [PATCH 12/19] Kotlin format --- app/src/main/java/com/jerboa/MainActivity.kt | 8 +- .../java/com/jerboa/feat/SwipeToAction.kt | 3 - .../ui/components/comment/CommentNode.kt | 128 +++++++------ .../ui/components/comment/CommentNodes.kt | 10 +- .../ui/components/common/SwipeToAction.kt | 14 +- .../components/community/CommunityActivity.kt | 2 +- .../ui/components/home/BottomNavActivity.kt | 5 +- .../jerboa/ui/components/home/HomeActivity.kt | 2 +- .../person/PersonProfileActivity.kt | 46 ++--- .../jerboa/ui/components/post/PostActivity.kt | 88 ++++----- .../jerboa/ui/components/post/PostListing.kt | 169 +++++++++--------- .../jerboa/ui/components/post/PostListings.kt | 17 +- .../components/settings/SettingsActivity.kt | 1 - .../lookandfeel/LookAndFeelActivity.kt | 16 +- 14 files changed, 251 insertions(+), 258 deletions(-) diff --git a/app/src/main/java/com/jerboa/MainActivity.kt b/app/src/main/java/com/jerboa/MainActivity.kt index 18a216399..6e936aacd 100644 --- a/app/src/main/java/com/jerboa/MainActivity.kt +++ b/app/src/main/java/com/jerboa/MainActivity.kt @@ -320,7 +320,7 @@ class MainActivity : AppCompatActivity() { onBack = appState::popBackStack, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum(), ) } @@ -358,7 +358,7 @@ class MainActivity : AppCompatActivity() { drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum(), ) } @@ -470,7 +470,7 @@ class MainActivity : AppCompatActivity() { blurNSFW = appSettings.blurNSFW, showPostLinkPreview = appSettings.showPostLinkPreviews, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum(), ) } } @@ -504,7 +504,7 @@ class MainActivity : AppCompatActivity() { blurNSFW = appSettings.blurNSFW, showPostLinkPreview = appSettings.showPostLinkPreviews, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum(), ) } diff --git a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt index 25bf616e2..5f95c80b3 100644 --- a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt @@ -7,9 +7,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.unit.dp import com.jerboa.R enum class SwipeToActionType { @@ -20,7 +18,6 @@ enum class SwipeToActionType { ; companion object { - const val START_THRESHOLD = 0.05f fun getActionToRangeList(actions: List): List, SwipeToActionType>> { diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index 9ecd939b0..97611abb2 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -218,7 +218,7 @@ fun LazyListScope.commentNodeItem( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: SwipeToActionPreset + swipeToActionPreset: SwipeToActionPreset, ) { val commentView = node.commentView val commentId = commentView.comment.id @@ -237,7 +237,7 @@ fun LazyListScope.commentNodeItem( val showMoreChildren = isExpanded(commentId) && node.children.isEmpty() && - commentView.counts.child_count > 0 && !isFlat + commentView.counts.child_count > 0 && !isFlat increaseLazyListIndexTracker() // TODO Needs a contentType @@ -250,19 +250,19 @@ fun LazyListScope.commentNodeItem( val border = Border(SMALL_PADDING, borderColor) var instantScores by - remember { - mutableStateOf( - InstantScores( - myVote = commentView.my_vote, - score = commentView.counts.score, - upvotes = commentView.counts.upvotes, - downvotes = commentView.counts.downvotes, - ), - ) - } + remember { + mutableStateOf( + InstantScores( + myVote = commentView.my_vote, + score = commentView.counts.score, + upvotes = commentView.counts.upvotes, + downvotes = commentView.counts.downvotes, + ), + ) + } val swipeState = rememberSwipeActionState(swipeToActionPreset) { - when(it) { + when (it) { SwipeToActionType.Upvote -> { instantScores = instantScores.update(VoteType.Upvote) @@ -290,10 +290,10 @@ fun LazyListScope.commentNodeItem( ) { Column( modifier = - Modifier - .padding( - start = offset, - ), + Modifier + .padding( + start = offset, + ), ) { Column( modifier = Modifier.border(start = border), @@ -301,10 +301,10 @@ fun LazyListScope.commentNodeItem( HorizontalDivider(modifier = Modifier.padding(start = if (node.depth == 0) 0.dp else border.strokeWidth)) Column( modifier = - Modifier.padding( - start = offset2, - end = MEDIUM_PADDING, - ), + Modifier.padding( + start = offset2, + end = MEDIUM_PADDING, + ), ) { if (showPostAndCommunityContext) { PostAndCommunityContextHeader( @@ -406,19 +406,17 @@ fun LazyListScope.commentNodeItem( } } - if(swipeToActionPreset != SwipeToActionPreset.DISABLED) { + if (swipeToActionPreset != SwipeToActionPreset.DISABLED) { SwipeToAction( swipeToActionPreset = swipeToActionPreset, swipeableContent = swipeableContent, - swipeState = swipeState + swipeState = swipeState, ) } else { Row { swipeableContent() } } - - } increaseLazyListIndexTracker() @@ -471,7 +469,7 @@ fun LazyListScope.commentNodeItem( showScores = showScores, admins = admins, moderators = moderators, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } @@ -514,7 +512,7 @@ fun LazyListScope.missingCommentNodeItem( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: SwipeToActionPreset + swipeToActionPreset: SwipeToActionPreset, ) { val commentId = node.missingCommentView.commentId @@ -545,10 +543,10 @@ fun LazyListScope.missingCommentNodeItem( ) { Column( modifier = - Modifier - .padding( - start = offset, - ), + Modifier + .padding( + start = offset, + ), ) { Column( modifier = Modifier.border(start = border), @@ -556,10 +554,10 @@ fun LazyListScope.missingCommentNodeItem( HorizontalDivider(modifier = Modifier.padding(start = if (node.depth == 0) 0.dp else border.strokeWidth)) Column( modifier = - Modifier.padding( - start = offset2, - end = MEDIUM_PADDING, - ), + Modifier.padding( + start = offset2, + end = MEDIUM_PADDING, + ), ) { AnimatedVisibility( visible = isExpanded(commentId) || showCollapsedCommentContent, @@ -619,7 +617,7 @@ fun LazyListScope.missingCommentNodeItem( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } @@ -651,10 +649,10 @@ private fun ShowMoreChildrenNode( ) { Column( modifier = - Modifier - .padding( - start = offset, - ), + Modifier + .padding( + start = offset, + ), ) { HorizontalDivider() Column( @@ -778,15 +776,15 @@ fun CommentFooterLine( Row( horizontalArrangement = Arrangement.End, modifier = - Modifier - .fillMaxWidth() - .combinedClickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onClick, - onLongClick = onLongClick, - ) - .padding(top = LARGE_PADDING, bottom = SMALL_PADDING), + Modifier + .fillMaxWidth() + .combinedClickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = onClick, + onLongClick = onLongClick, + ) + .padding(top = LARGE_PADDING, bottom = SMALL_PADDING), ) { Row( horizontalArrangement = Arrangement.spacedBy(XXL_PADDING), @@ -817,24 +815,24 @@ fun CommentFooterLine( ) ActionBarButton( icon = - if (commentView.saved) { - Icons.Filled.Bookmark - } else { - Icons.Outlined.BookmarkBorder - }, + if (commentView.saved) { + Icons.Filled.Bookmark + } else { + Icons.Outlined.BookmarkBorder + }, contentDescription = - if (commentView.saved) { - stringResource(R.string.removeBookmark) - } else { - stringResource(R.string.addBookmark) - }, + if (commentView.saved) { + stringResource(R.string.removeBookmark) + } else { + stringResource(R.string.addBookmark) + }, onClick = { onSaveClick(commentView) }, contentColor = - if (commentView.saved) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.onBackground.muted - }, + if (commentView.saved) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.onBackground.muted + }, account = account, ) ActionBarButton( @@ -898,7 +896,7 @@ fun CommentNodesPreview() { blurNSFW = 1, account = AnonAccount, showScores = true, - swipeToActionPreset = SwipeToActionPreset.DEFAULT + swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt index 187d95a13..abb6d5264 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt @@ -65,7 +65,7 @@ fun CommentNodes( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: SwipeToActionPreset + swipeToActionPreset: SwipeToActionPreset, ) { LazyColumn(state = listState) { commentNodeItems( @@ -107,7 +107,7 @@ fun CommentNodes( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) item { Spacer(modifier = Modifier.height(100.dp)) @@ -154,7 +154,7 @@ fun LazyListScope.commentNodeItems( showAvatar: Boolean, blurNSFW: Int, showScores: Boolean, - swipeToActionPreset: SwipeToActionPreset + swipeToActionPreset: SwipeToActionPreset, ) { nodes.forEach { node -> when (node) { @@ -198,7 +198,7 @@ fun LazyListScope.commentNodeItems( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) is MissingCommentNode -> @@ -241,7 +241,7 @@ fun LazyListScope.commentNodeItems( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index 375c4dcee..0c3fedab0 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -42,13 +42,13 @@ fun SwipeToAction( val haptic = LocalHapticFeedback.current val leftActionsRanges = - remember (swipeToActionPreset) {SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions)} + remember(swipeToActionPreset) { SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions) } val rightActionsRanges = - remember (swipeToActionPreset) {SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions)} + remember(swipeToActionPreset) { SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions) } fun actionByState(state: SwipeToDismissBoxState): Pair, SwipeToActionType>? { return when (state.targetValue) { - SwipeToDismissBoxValue.StartToEnd -> { + SwipeToDismissBoxValue.StartToEnd -> { leftActionsRanges.findLast { swipeState.progress in it.first } } @@ -97,7 +97,9 @@ fun SwipeToAction( .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) .fillMaxHeight() .background(color = color) - .align(if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) Alignment.TopEnd else Alignment.TopStart), + .align( + if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) Alignment.TopEnd else Alignment.TopStart, + ), contentAlignment = if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) { Alignment.CenterStart @@ -138,9 +140,9 @@ fun rememberSwipeActionState( They didn't fix it with new SwipeToDismissBoxState */ val leftActionsRanges = - remember(swipeToActionPreset) {SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions)} + remember(swipeToActionPreset) { SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions) } val rightActionsRanges = - remember(swipeToActionPreset) {SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions)} + remember(swipeToActionPreset) { SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions) } val progressState = remember { mutableFloatStateOf(1.0f) } val dismissState = rememberSwipeToDismissBoxState( diff --git a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt index 6942d6ed4..f2ae180af 100644 --- a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt @@ -421,7 +421,7 @@ fun CommunityActivity( showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, showPostAppendRetry = communityViewModel.postsRes is ApiState.AppendingFailure, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt index 859c0ad6a..971189baa 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/BottomNavActivity.kt @@ -42,7 +42,6 @@ import arrow.core.Either import com.jerboa.JerboaAppState import com.jerboa.R import com.jerboa.db.entity.AppSettings -import com.jerboa.feat.SwipeToActionPreset import com.jerboa.feat.doIfReadyElseDisplayInfo import com.jerboa.model.AccountViewModel import com.jerboa.model.AppSettingsViewModel @@ -258,7 +257,7 @@ fun BottomNavActivity( drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum(), ) } @@ -278,7 +277,7 @@ fun BottomNavActivity( drawerState = drawerState, markAsReadOnScroll = appSettings.markAsReadOnScroll, postActionbarMode = appSettings.postActionbarMode, - swipeToActionPreset = appSettings.swipeToActionPreset.toEnum() + swipeToActionPreset = appSettings.swipeToActionPreset.toEnum(), ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt index c111a5bdb..9ed654aa6 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt @@ -422,7 +422,7 @@ fun MainPostListingsContent( showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, showPostAppendRetry = homeViewModel.postsRes is ApiState.AppendingFailure, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt index 1a6a826e5..7869d170a 100644 --- a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt @@ -123,7 +123,7 @@ fun PersonProfileActivity( markAsReadOnScroll: Boolean, postActionbarMode: Int, onBack: (() -> Unit)? = null, - swipeToActionPreset: SwipeToActionPreset + swipeToActionPreset: SwipeToActionPreset, ) { Log.d("jerboa", "got to person activity") @@ -189,11 +189,11 @@ fun PersonProfileActivity( PersonProfileHeader( scrollBehavior = scrollBehavior, personName = - if (savedMode) { - ctx.getString(R.string.bookmarks_activity_saved) - } else { - person.name - }, + if (savedMode) { + ctx.getString(R.string.bookmarks_activity_saved) + } else { + person.name + }, myProfile = account.id == person.id, selectedSortType = personProfileViewModel.sortType, onClickSortType = { sortType -> @@ -274,7 +274,7 @@ fun PersonProfileActivity( snackbarHostState = snackbarHostState, showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) }, ) @@ -310,7 +310,7 @@ fun UserTabs( snackbarHostState: SnackbarHostState, showScores: Boolean, postActionbarMode: Int, - swipeToActionPreset: SwipeToActionPreset + swipeToActionPreset: SwipeToActionPreset, ) { val tabTitles = if (savedMode) { @@ -391,9 +391,9 @@ fun UserTabs( LazyColumn( state = listState, modifier = - Modifier - .fillMaxSize() - .simpleVerticalScrollbar(listState), + Modifier + .fillMaxSize() + .simpleVerticalScrollbar(listState), ) { item(contentType = "topSection") { PersonProfileTopSection( @@ -436,9 +436,9 @@ fun UserTabs( UserTab.Posts.ordinal -> { Box( modifier = - Modifier - .pullRefresh(pullRefreshState) - .fillMaxSize(), + Modifier + .pullRefresh(pullRefreshState) + .fillMaxSize(), ) { JerboaPullRefreshIndicator( personProfileViewModel.personDetailsRes.isRefreshing(), @@ -473,10 +473,10 @@ fun UserTabs( CreatePostLike( post_id = pv.post.id, score = - newVote( - pv.my_vote, - VoteType.Upvote, - ).toLong(), + newVote( + pv.my_vote, + VoteType.Upvote, + ).toLong(), ), ) } @@ -622,7 +622,7 @@ fun UserTabs( showScores = showScores, postActionbarMode = postActionbarMode, showPostAppendRetry = personProfileViewModel.personDetailsRes is ApiState.AppendingFailure, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } else -> {} @@ -685,9 +685,9 @@ fun UserTabs( Box( modifier = - Modifier - .pullRefresh(pullRefreshState) - .fillMaxSize(), + Modifier + .pullRefresh(pullRefreshState) + .fillMaxSize(), ) { JerboaPullRefreshIndicator( personProfileViewModel.personDetailsRes.isRefreshing(), @@ -843,7 +843,7 @@ fun UserTabs( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt index 30c96e082..55484c448 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt @@ -135,7 +135,7 @@ fun PostActivity( blurNSFW: Int, showPostLinkPreview: Boolean, postActionbarMode: Int, - swipeToActionPreset: SwipeToActionPreset + swipeToActionPreset: SwipeToActionPreset, ) { Log.d("jerboa", "got to post activity") @@ -191,33 +191,33 @@ fun PostActivity( Scaffold( snackbarHost = { JerboaSnackbarHost(snackbarHostState) }, modifier = - Modifier - .nestedScroll(scrollBehavior.nestedScrollConnection) - .semantics { testTagsAsResourceId = true } - .nestedScroll(scrollBehavior.nestedScrollConnection) - .focusRequester(focusRequester) - .focusable() - .onKeyEvent { keyEvent -> - if (navigateParentCommentsWithVolumeButtons) { - when (keyEvent.key) { - Key.VolumeUp -> { - scrollToPreviousParentComment(scope, parentListStateIndexes, listState) - true - } + Modifier + .nestedScroll(scrollBehavior.nestedScrollConnection) + .semantics { testTagsAsResourceId = true } + .nestedScroll(scrollBehavior.nestedScrollConnection) + .focusRequester(focusRequester) + .focusable() + .onKeyEvent { keyEvent -> + if (navigateParentCommentsWithVolumeButtons) { + when (keyEvent.key) { + Key.VolumeUp -> { + scrollToPreviousParentComment(scope, parentListStateIndexes, listState) + true + } - Key.VolumeDown -> { - scrollToNextParentComment(scope, parentListStateIndexes, listState) - true - } + Key.VolumeDown -> { + scrollToNextParentComment(scope, parentListStateIndexes, listState) + true + } - else -> { - false + else -> { + false + } } + } else { + false } - } else { - false - } - }, + }, bottomBar = { if (showParentCommentNavigationButtons) { CommentNavigationBottomAppBar( @@ -272,9 +272,9 @@ fun PostActivity( content = { padding -> Box( modifier = - Modifier - .fillMaxSize() - .pullRefresh(pullRefreshState), + Modifier + .fillMaxSize() + .pullRefresh(pullRefreshState), ) { parentListStateIndexes.clear() lazyListIndexTracker = 2 @@ -300,10 +300,10 @@ fun PostActivity( LazyColumn( state = listState, modifier = - Modifier - .padding(top = padding.calculateTopPadding()) - .simpleVerticalScrollbar(listState) - .testTag("jerboa:comments"), + Modifier + .padding(top = padding.calculateTopPadding()) + .simpleVerticalScrollbar(listState) + .testTag("jerboa:comments"), ) { item(key = "${postView.post.id}_listing", "post_listing") { PostListing( @@ -323,10 +323,10 @@ fun PostActivity( CreatePostLike( post_id = pv.post.id, score = - newVote( - postView.my_vote, - VoteType.Upvote, - ).toLong(), + newVote( + postView.my_vote, + VoteType.Upvote, + ).toLong(), ), ) } @@ -463,7 +463,7 @@ fun PostActivity( showIfRead = false, showScores = siteViewModel.showScores(), postActionbarMode = postActionbarMode, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } @@ -562,10 +562,10 @@ fun PostActivity( CreateCommentLike( comment_id = cv.comment.id, score = - newVote( - cv.my_vote, - VoteType.Upvote, - ).toLong(), + newVote( + cv.my_vote, + VoteType.Upvote, + ).toLong(), ), ) } @@ -687,13 +687,13 @@ fun PostActivity( showCollapsedCommentContent = showCollapsedCommentContent, showActionBar = { commentId -> showActionBarByDefault xor - commentsWithToggledActionBar.contains( - commentId, - ) + commentsWithToggledActionBar.contains( + commentId, + ) }, blurNSFW = blurNSFW, showScores = siteViewModel.showScores(), - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) item { Spacer(modifier = Modifier.height(100.dp)) diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt index 15f347a58..c07006cd1 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt @@ -357,10 +357,10 @@ fun PostTitleAndImageLink( Column( modifier = - Modifier.padding( - vertical = MEDIUM_PADDING, - horizontal = MEDIUM_PADDING, - ), + Modifier.padding( + vertical = MEDIUM_PADDING, + horizontal = MEDIUM_PADDING, + ), ) { // Title of the post PostName( @@ -373,11 +373,11 @@ fun PostTitleAndImageLink( url = url, blur = blurNSFW.toEnum().needBlur(postView), modifier = - Modifier - .combinedClickable( - onClick = { appState.openImageViewer(url) }, - onLongClick = { appState.showLinkPopup(url) }, - ), + Modifier + .combinedClickable( + onClick = { appState.openImageViewer(url) }, + onLongClick = { appState.showLinkPopup(url) }, + ), ) } @@ -471,15 +471,15 @@ fun PostBody( colors = CARD_COLORS, shape = MaterialTheme.shapes.medium, modifier = - Modifier - .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) - .fillMaxWidth(), + Modifier + .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) + .fillMaxWidth(), content = { if (fullBody) { Column( modifier = - Modifier - .padding(MEDIUM_PADDING), + Modifier + .padding(MEDIUM_PADDING), ) { if (viewSource) { SelectionContainer { @@ -646,9 +646,9 @@ fun PostFooterLine( horizontalArrangement = horizontalArrangement, verticalAlignment = Alignment.Bottom, modifier = - modifier - .fillMaxWidth() - .padding(bottom = SMALL_PADDING), + modifier + .fillMaxWidth() + .padding(bottom = SMALL_PADDING), ) { // Right handside shows the comments on the left side if (postActionbar == PostActionbarMode.RightHandShort) { @@ -698,24 +698,24 @@ fun PostFooterLine( } ActionBarButton( icon = - if (postView.saved) { - Icons.Filled.Bookmark - } else { - Icons.Outlined.BookmarkBorder - }, + if (postView.saved) { + Icons.Filled.Bookmark + } else { + Icons.Outlined.BookmarkBorder + }, contentDescription = - if (postView.saved) { - stringResource(R.string.removeBookmark) - } else { - stringResource(R.string.addBookmark) - }, + if (postView.saved) { + stringResource(R.string.removeBookmark) + } else { + stringResource(R.string.addBookmark) + }, onClick = { onSaveClick(postView) }, contentColor = - if (postView.saved) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.onBackground.muted - }, + if (postView.saved) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.onBackground.muted + }, account = account, ) ActionBarButton( @@ -870,7 +870,7 @@ fun PreviewPostListingCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, - swipeToActionPreset = SwipeToActionPreset.DEFAULT + swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) } @@ -910,7 +910,7 @@ fun PreviewLinkPostListing() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, - swipeToActionPreset = SwipeToActionPreset.DEFAULT + swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) } @@ -950,7 +950,7 @@ fun PreviewImagePostListingCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, - swipeToActionPreset = SwipeToActionPreset.DEFAULT + swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) } @@ -990,7 +990,7 @@ fun PreviewImagePostListingSmallCard() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, - swipeToActionPreset = SwipeToActionPreset.DEFAULT + swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) } @@ -1030,7 +1030,7 @@ fun PreviewLinkNoThumbnailPostListing() { showIfRead = true, showScores = true, postActionbarMode = PostActionbarMode.Long.ordinal, - swipeToActionPreset = SwipeToActionPreset.DEFAULT + swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) } @@ -1071,25 +1071,25 @@ fun PostListing( showIfRead: Boolean, showScores: Boolean, postActionbarMode: Int, - swipeToActionPreset: SwipeToActionPreset + swipeToActionPreset: SwipeToActionPreset, ) { // This stores vote data var instantScores by - remember { - mutableStateOf( - InstantScores( - myVote = postView.my_vote, - score = postView.counts.score, - upvotes = postView.counts.upvotes, - downvotes = postView.counts.downvotes, - ), - ) - } + remember { + mutableStateOf( + InstantScores( + myVote = postView.my_vote, + score = postView.counts.score, + upvotes = postView.counts.upvotes, + downvotes = postView.counts.downvotes, + ), + ) + } var viewSource by remember { mutableStateOf(false) } val swipeState = rememberSwipeActionState(swipeToActionPreset) { - when(it) { + when (it) { SwipeToActionType.Upvote -> { instantScores = instantScores.update(VoteType.Upvote) @@ -1236,18 +1236,17 @@ fun PostListing( } } - if(swipeToActionPreset != SwipeToActionPreset.DISABLED) { + if (swipeToActionPreset != SwipeToActionPreset.DISABLED) { SwipeToAction( swipeToActionPreset = swipeToActionPreset, swipeableContent = swipeableContent, - swipeState = swipeState + swipeState = swipeState, ) } else { Row { swipeableContent() } } - } @Composable @@ -1262,9 +1261,9 @@ fun PostVotingTile( Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = - Modifier - .fillMaxHeight() - .padding(end = MEDIUM_PADDING), + Modifier + .fillMaxHeight() + .padding(end = MEDIUM_PADDING), ) { VoteGeneric( myVote = instantScores.myVote, @@ -1322,19 +1321,19 @@ fun PostListingList( ) { Column( modifier = - Modifier - .padding( - horizontal = MEDIUM_PADDING, - vertical = MEDIUM_PADDING, - ) - .testTag("jerboa:post"), + Modifier + .padding( + horizontal = MEDIUM_PADDING, + vertical = MEDIUM_PADDING, + ) + .testTag("jerboa:post"), ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = - Arrangement.spacedBy( - SMALL_PADDING, - ), + Arrangement.spacedBy( + SMALL_PADDING, + ), ) { if (showVotingArrowsInListView) { PostVotingTile( @@ -1348,9 +1347,9 @@ fun PostListingList( } Column( modifier = - Modifier - .weight(1f) - .clickable { onPostClick(postView) }, + Modifier + .weight(1f) + .clickable { onPostClick(postView) }, verticalArrangement = Arrangement.spacedBy(SMALL_PADDING), ) { PostName(postView = postView, showIfRead = showIfRead) @@ -1407,10 +1406,10 @@ fun PostListingList( } Text( text = - stringResource( - R.string.post_listing_comments_count, - postView.counts.comments, - ), + stringResource( + R.string.post_listing_comments_count, + postView.counts.comments, + ), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onBackground.muted, ) @@ -1498,14 +1497,14 @@ private fun ThumbnailTile( painter = painterResource(id = R.drawable.triangle), contentDescription = null, modifier = - Modifier - .size(THUMBNAIL_CARET_SIZE) - .align(Alignment.BottomEnd), + Modifier + .size(THUMBNAIL_CARET_SIZE) + .align(Alignment.BottomEnd), tint = - when (postType) { - PostType.Video -> MaterialTheme.jerboaColorScheme.videoHighlight - else -> MaterialTheme.jerboaColorScheme.imageHighlight - }, + when (postType) { + PostType.Video -> MaterialTheme.jerboaColorScheme.videoHighlight + else -> MaterialTheme.jerboaColorScheme.imageHighlight + }, ) } } @@ -1613,10 +1612,10 @@ fun PostListingCard( ) { Column( modifier = - Modifier - .padding(vertical = MEDIUM_PADDING) - .clickable { onPostClick(postView) } - .testTag("jerboa:post"), + Modifier + .padding(vertical = MEDIUM_PADDING) + .clickable { onPostClick(postView) } + .testTag("jerboa:post"), // see https://stackoverflow.com/questions/77010371/prevent-popup-from-adding-padding-in-a-column-with-arrangement-spacedbylarge-p // verticalArrangement = Arrangement.spacedBy(LARGE_PADDING), ) { @@ -1700,9 +1699,9 @@ fun MetadataCard(post: Post) { OutlinedCard( shape = MaterialTheme.shapes.medium, modifier = - Modifier - .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) - .fillMaxWidth(), + Modifier + .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) + .fillMaxWidth(), content = { Column( modifier = Modifier.padding(MEDIUM_PADDING), diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt index 3aef918cf..60be3a843 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt @@ -1,7 +1,6 @@ package com.jerboa.ui.components.post import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -82,16 +81,16 @@ fun PostListings( showScores: Boolean, postActionbarMode: Int, showPostAppendRetry: Boolean, - swipeToActionPreset: SwipeToActionPreset + swipeToActionPreset: SwipeToActionPreset, ) { LazyColumn( state = listState, modifier = - Modifier - .padding(padding) - .fillMaxSize() - .simpleVerticalScrollbar(listState) - .testTag("jerboa:posts"), + Modifier + .padding(padding) + .fillMaxSize() + .simpleVerticalScrollbar(listState) + .testTag("jerboa:posts"), ) { item(contentType = "aboveContent") { contentAboveListings() @@ -134,7 +133,7 @@ fun PostListings( showIfRead = showIfRead, showScores = showScores, postActionbarMode = postActionbarMode, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ).let { if (!postView.read && markAsReadOnScroll) { DisposableEffect(key1 = postView.post.id) { @@ -210,6 +209,6 @@ fun PreviewPostListings() { showScores = true, postActionbarMode = 0, showPostAppendRetry = false, - swipeToActionPreset = SwipeToActionPreset.DEFAULT + swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt b/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt index 728cd00ca..01c3407b7 100644 --- a/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/settings/SettingsActivity.kt @@ -47,7 +47,6 @@ fun SettingsActivity( content = { padding -> Column(modifier = Modifier.padding(padding)) { SettingsMenuLink( - title = { Text(stringResource(R.string.settings_activity_look_and_feel)) }, icon = { Icon( diff --git a/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt b/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt index b52d59633..f5a15489b 100644 --- a/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt @@ -148,9 +148,9 @@ fun LookAndFeelActivity( content = { padding -> Column( modifier = - Modifier - .verticalScroll(scrollState) - .padding(padding), + Modifier + .verticalScroll(scrollState) + .padding(padding), ) { SettingsListDropdown( title = { @@ -183,10 +183,10 @@ fun LookAndFeelActivity( title = { Text( text = - stringResource( - R.string.look_and_feel_font_size, - fontSizeState.value.toInt(), - ), + stringResource( + R.string.look_and_feel_font_size, + fontSizeState.value.toInt(), + ), ) }, onValueChangeFinished = { updateAppSettings() }, @@ -400,4 +400,4 @@ fun LookAndFeelActivity( } }, ) -} \ No newline at end of file +} From 23e854085cc048d0b68d47e99c9d0dec60c073a6 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Tue, 30 Jan 2024 01:49:01 +0300 Subject: [PATCH 13/19] use ordinal of enum in AppDB instead of int --- app/src/main/java/com/jerboa/db/AppDB.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/jerboa/db/AppDB.kt b/app/src/main/java/com/jerboa/db/AppDB.kt index 5a9aaab11..de1d84daa 100644 --- a/app/src/main/java/com/jerboa/db/AppDB.kt +++ b/app/src/main/java/com/jerboa/db/AppDB.kt @@ -12,6 +12,7 @@ import com.jerboa.db.dao.AccountDao import com.jerboa.db.dao.AppSettingsDao import com.jerboa.db.entity.Account import com.jerboa.db.entity.AppSettings +import com.jerboa.feat.SwipeToActionPreset import java.util.concurrent.Executors val APP_SETTINGS_DEFAULT = @@ -39,7 +40,7 @@ val APP_SETTINGS_DEFAULT = showPostLinkPreviews = true, postActionbarMode = 0, autoPlayGifs = false, - swipeToActionPreset = 1, + swipeToActionPreset = SwipeToActionPreset.DEFAULT.ordinal, ) @Database( From 93e5c5e67eef012b97047c8c3c05da614f76f9aa Mon Sep 17 00:00:00 2001 From: snow4dv Date: Sun, 4 Feb 2024 20:58:57 +0300 Subject: [PATCH 14/19] Fixed behaviour when downvotes disables/when not logged in --- .../java/com/jerboa/feat/SwipeToAction.kt | 11 +- .../ui/components/comment/CommentNode.kt | 45 ++-- .../ui/components/common/SwipeToAction.kt | 52 +++-- .../components/community/CommunityActivity.kt | 6 + .../jerboa/ui/components/home/HomeActivity.kt | 6 + .../person/PersonProfileActivity.kt | 5 + .../jerboa/ui/components/post/PostListing.kt | 201 ++++++++++-------- .../jerboa/ui/components/post/PostListings.kt | 4 + .../lookandfeel/LookAndFeelActivity.kt | 13 ++ 9 files changed, 205 insertions(+), 138 deletions(-) diff --git a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt index 5f95c80b3..f2d6aca35 100644 --- a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt @@ -1,6 +1,7 @@ package com.jerboa.feat import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.outlined.Comment import androidx.compose.material.icons.outlined.Bookmark import androidx.compose.material.icons.outlined.Comment import androidx.compose.material3.MaterialTheme @@ -28,14 +29,6 @@ enum class SwipeToActionType { .rangeUntil(if (index == actions.size - 1) 1f else (start + delta * (index + 1))) to it } } - - fun getDefaultLeftActions(): List { - return listOf(Reply, Save) - } - - fun getDefaultRightActions(): List { - return listOf(Upvote, Downvote) - } } @Composable @@ -43,7 +36,7 @@ enum class SwipeToActionType { return when (this) { Upvote -> ImageVector.vectorResource(id = R.drawable.up_outline) Downvote -> ImageVector.vectorResource(id = R.drawable.down_outline) - Reply -> Icons.Outlined.Comment + Reply -> Icons.AutoMirrored.Outlined.Comment Save -> Icons.Outlined.Bookmark } } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index 97611abb2..f00f24645 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -58,11 +58,14 @@ import com.jerboa.datatypes.sampleReplyCommentView import com.jerboa.datatypes.sampleSecondReplyCommentView import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount +import com.jerboa.db.entity.isAnon +import com.jerboa.db.entity.isReady import com.jerboa.feat.InstantScores import com.jerboa.feat.SwipeToActionPreset import com.jerboa.feat.SwipeToActionType import com.jerboa.feat.VoteType import com.jerboa.feat.canMod +import com.jerboa.feat.isReadyAndIfNotShowSimplifiedInfoToast import com.jerboa.isPostCreator import com.jerboa.ui.components.common.ActionBarButton import com.jerboa.ui.components.common.CommentOrPostNodeHeader @@ -249,6 +252,8 @@ fun LazyListScope.commentNodeItem( val borderColor = calculateBorderColor(backgroundColor, node.depth) val border = Border(SMALL_PADDING, borderColor) + val ctx = LocalContext.current + var instantScores by remember { mutableStateOf( @@ -261,23 +266,28 @@ fun LazyListScope.commentNodeItem( ) } - val swipeState = rememberSwipeActionState(swipeToActionPreset) { - when (it) { - SwipeToActionType.Upvote -> { - instantScores = - instantScores.update(VoteType.Upvote) - onUpvoteClick(commentView) - } - SwipeToActionType.Downvote -> { - instantScores = - instantScores.update(VoteType.Downvote) - onDownvoteClick(commentView) - } - SwipeToActionType.Reply -> { - onReplyClick(commentView) - } - SwipeToActionType.Save -> { - onSaveClick(commentView) + val swipeState = rememberSwipeActionState( + swipeToActionPreset = swipeToActionPreset, + enableDownVotes = enableDownVotes + ) { + if(account.isReadyAndIfNotShowSimplifiedInfoToast(ctx)) { + when (it) { + SwipeToActionType.Upvote -> { + instantScores = + instantScores.update(VoteType.Upvote) + onUpvoteClick(commentView) + } + SwipeToActionType.Downvote -> { + instantScores = + instantScores.update(VoteType.Downvote) + onDownvoteClick(commentView) + } + SwipeToActionType.Reply -> { + onReplyClick(commentView) + } + SwipeToActionType.Save -> { + onSaveClick(commentView) + } } } } @@ -409,6 +419,7 @@ fun LazyListScope.commentNodeItem( if (swipeToActionPreset != SwipeToActionPreset.DISABLED) { SwipeToAction( swipeToActionPreset = swipeToActionPreset, + enableDownVotes = enableDownVotes, swipeableContent = swipeableContent, swipeState = swipeState, ) diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index 0c3fedab0..2d4915c16 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -36,15 +36,22 @@ import com.jerboa.feat.SwipeToActionType.Companion.START_THRESHOLD @ExperimentalMaterial3Api fun SwipeToAction( swipeToActionPreset: SwipeToActionPreset, + enableDownVotes: Boolean = true, swipeableContent: @Composable RowScope.() -> Unit, swipeState: SwipeToDismissBoxState, ) { val haptic = LocalHapticFeedback.current val leftActionsRanges = - remember(swipeToActionPreset) { SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions) } + remember(swipeToActionPreset) { + SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions + .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }) + } val rightActionsRanges = - remember(swipeToActionPreset) { SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions) } + remember(swipeToActionPreset) { + SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions + .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }) + } fun actionByState(state: SwipeToDismissBoxState): Pair, SwipeToActionType>? { return when (state.targetValue) { @@ -88,24 +95,24 @@ fun SwipeToAction( ) Box( modifier = - Modifier - .fillMaxSize(), + Modifier + .fillMaxSize(), ) { Box( modifier = - Modifier - .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) - .fillMaxHeight() - .background(color = color) - .align( - if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) Alignment.TopEnd else Alignment.TopStart, - ), + Modifier + .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) + .fillMaxHeight() + .background(color = color) + .align( + if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) Alignment.TopEnd else Alignment.TopStart, + ), contentAlignment = - if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) { - Alignment.CenterStart - } else { - Alignment.CenterEnd - }, + if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) { + Alignment.CenterStart + } else { + Alignment.CenterEnd + }, ) { val tint = Color.White val modifier = @@ -133,16 +140,23 @@ fun SwipeToAction( @Composable fun rememberSwipeActionState( swipeToActionPreset: SwipeToActionPreset, - onAction: (action: SwipeToActionType) -> Unit, + enableDownVotes: Boolean = true, + onAction: (action: SwipeToActionType) -> Unit ): SwipeToDismissBoxState { /* This hacky solution is required because confirmValueChange lambda doesn't pass progress state They didn't fix it with new SwipeToDismissBoxState */ val leftActionsRanges = - remember(swipeToActionPreset) { SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions) } + remember(swipeToActionPreset) { + SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions + .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }) + } val rightActionsRanges = - remember(swipeToActionPreset) { SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions) } + remember(swipeToActionPreset) { + SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions + .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }) + } val progressState = remember { mutableFloatStateOf(1.0f) } val dismissState = rememberSwipeToDismissBoxState( diff --git a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt index f2ae180af..92c7c0699 100644 --- a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt @@ -44,6 +44,7 @@ import com.jerboa.hostName import com.jerboa.model.AccountViewModel import com.jerboa.model.AppSettingsViewModel import com.jerboa.model.CommunityViewModel +import com.jerboa.model.ReplyItem import com.jerboa.model.SiteViewModel import com.jerboa.scrollToTop import com.jerboa.ui.components.ban.BanFromCommunityReturn @@ -313,6 +314,11 @@ fun CommunityActivity( ) } }, + onReplyClick = { pv -> + appState.toCommentReply( + replyItem = ReplyItem.PostItem(pv), + ) + }, onEditPostClick = { postView -> appState.toPostEdit( postView = postView, diff --git a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt index 9ed654aa6..2fcbebcf9 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt @@ -49,6 +49,7 @@ import com.jerboa.feat.newVote import com.jerboa.model.AccountViewModel import com.jerboa.model.AppSettingsViewModel import com.jerboa.model.HomeViewModel +import com.jerboa.model.ReplyItem import com.jerboa.model.SiteViewModel import com.jerboa.scrollToTop import com.jerboa.ui.components.ban.BanFromCommunityReturn @@ -320,6 +321,11 @@ fun MainPostListingsContent( ) } }, + onReplyClick = { pv -> + appState.toCommentReply( + replyItem = ReplyItem.PostItem(pv), + ) + }, onEditPostClick = { postView -> appState.toPostEdit( postView = postView, diff --git a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt index 7869d170a..ddcfdec60 100644 --- a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt @@ -519,6 +519,11 @@ fun UserTabs( ) } }, + onReplyClick = { pv -> + appState.toCommentReply( + replyItem = ReplyItem.PostItem(pv), + ) + }, onEditPostClick = { pv -> appState.toPostEdit( postView = pv, diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt index c07006cd1..3c92b9f5b 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt @@ -48,6 +48,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -79,6 +80,7 @@ import com.jerboa.feat.VoteType import com.jerboa.feat.amAdmin import com.jerboa.feat.amMod import com.jerboa.feat.canMod +import com.jerboa.feat.isReadyAndIfNotShowSimplifiedInfoToast import com.jerboa.feat.needBlur import com.jerboa.getPostType import com.jerboa.hostName @@ -357,10 +359,10 @@ fun PostTitleAndImageLink( Column( modifier = - Modifier.padding( - vertical = MEDIUM_PADDING, - horizontal = MEDIUM_PADDING, - ), + Modifier.padding( + vertical = MEDIUM_PADDING, + horizontal = MEDIUM_PADDING, + ), ) { // Title of the post PostName( @@ -373,11 +375,11 @@ fun PostTitleAndImageLink( url = url, blur = blurNSFW.toEnum().needBlur(postView), modifier = - Modifier - .combinedClickable( - onClick = { appState.openImageViewer(url) }, - onLongClick = { appState.showLinkPopup(url) }, - ), + Modifier + .combinedClickable( + onClick = { appState.openImageViewer(url) }, + onLongClick = { appState.showLinkPopup(url) }, + ), ) } @@ -471,15 +473,15 @@ fun PostBody( colors = CARD_COLORS, shape = MaterialTheme.shapes.medium, modifier = - Modifier - .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) - .fillMaxWidth(), + Modifier + .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) + .fillMaxWidth(), content = { if (fullBody) { Column( modifier = - Modifier - .padding(MEDIUM_PADDING), + Modifier + .padding(MEDIUM_PADDING), ) { if (viewSource) { SelectionContainer { @@ -646,9 +648,9 @@ fun PostFooterLine( horizontalArrangement = horizontalArrangement, verticalAlignment = Alignment.Bottom, modifier = - modifier - .fillMaxWidth() - .padding(bottom = SMALL_PADDING), + modifier + .fillMaxWidth() + .padding(bottom = SMALL_PADDING), ) { // Right handside shows the comments on the left side if (postActionbar == PostActionbarMode.RightHandShort) { @@ -698,24 +700,24 @@ fun PostFooterLine( } ActionBarButton( icon = - if (postView.saved) { - Icons.Filled.Bookmark - } else { - Icons.Outlined.BookmarkBorder - }, + if (postView.saved) { + Icons.Filled.Bookmark + } else { + Icons.Outlined.BookmarkBorder + }, contentDescription = - if (postView.saved) { - stringResource(R.string.removeBookmark) - } else { - stringResource(R.string.addBookmark) - }, + if (postView.saved) { + stringResource(R.string.removeBookmark) + } else { + stringResource(R.string.addBookmark) + }, onClick = { onSaveClick(postView) }, contentColor = - if (postView.saved) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.onBackground.muted - }, + if (postView.saved) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.onBackground.muted + }, account = account, ) ActionBarButton( @@ -724,7 +726,10 @@ fun PostFooterLine( account = account, onClick = { showMoreOptions = !showMoreOptions }, requiresAccount = false, - modifier = if (postActionbar == PostActionbarMode.LeftHandShort) Modifier.weight(1F, true) else Modifier, + modifier = if (postActionbar == PostActionbarMode.LeftHandShort) Modifier.weight( + 1F, + true + ) else Modifier, ) if (postActionbar == PostActionbarMode.LeftHandShort) { @@ -1073,38 +1078,47 @@ fun PostListing( postActionbarMode: Int, swipeToActionPreset: SwipeToActionPreset, ) { + val ctx = LocalContext.current // This stores vote data var instantScores by - remember { - mutableStateOf( - InstantScores( - myVote = postView.my_vote, - score = postView.counts.score, - upvotes = postView.counts.upvotes, - downvotes = postView.counts.downvotes, - ), - ) - } + remember { + mutableStateOf( + InstantScores( + myVote = postView.my_vote, + score = postView.counts.score, + upvotes = postView.counts.upvotes, + downvotes = postView.counts.downvotes, + ), + ) + } var viewSource by remember { mutableStateOf(false) } - val swipeState = rememberSwipeActionState(swipeToActionPreset) { - when (it) { - SwipeToActionType.Upvote -> { - instantScores = - instantScores.update(VoteType.Upvote) - onUpvoteClick(postView) - } - SwipeToActionType.Downvote -> { - instantScores = - instantScores.update(VoteType.Downvote) - onDownvoteClick(postView) - } - SwipeToActionType.Reply -> { - onReplyClick(postView) - } - SwipeToActionType.Save -> { - onSaveClick(postView) + val swipeState = rememberSwipeActionState( + swipeToActionPreset = swipeToActionPreset, + enableDownVotes = enableDownVotes + ) { + if (account.isReadyAndIfNotShowSimplifiedInfoToast(ctx)) { + when (it) { + SwipeToActionType.Upvote -> { + instantScores = + instantScores.update(VoteType.Upvote) + onUpvoteClick(postView) + } + + SwipeToActionType.Downvote -> { + instantScores = + instantScores.update(VoteType.Downvote) + onDownvoteClick(postView) + } + + SwipeToActionType.Reply -> { + onReplyClick(postView) + } + + SwipeToActionType.Save -> { + onSaveClick(postView) + } } } } @@ -1239,6 +1253,7 @@ fun PostListing( if (swipeToActionPreset != SwipeToActionPreset.DISABLED) { SwipeToAction( swipeToActionPreset = swipeToActionPreset, + enableDownVotes = enableDownVotes, swipeableContent = swipeableContent, swipeState = swipeState, ) @@ -1261,9 +1276,9 @@ fun PostVotingTile( Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = - Modifier - .fillMaxHeight() - .padding(end = MEDIUM_PADDING), + Modifier + .fillMaxHeight() + .padding(end = MEDIUM_PADDING), ) { VoteGeneric( myVote = instantScores.myVote, @@ -1321,19 +1336,19 @@ fun PostListingList( ) { Column( modifier = - Modifier - .padding( - horizontal = MEDIUM_PADDING, - vertical = MEDIUM_PADDING, - ) - .testTag("jerboa:post"), + Modifier + .padding( + horizontal = MEDIUM_PADDING, + vertical = MEDIUM_PADDING, + ) + .testTag("jerboa:post"), ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = - Arrangement.spacedBy( - SMALL_PADDING, - ), + Arrangement.spacedBy( + SMALL_PADDING, + ), ) { if (showVotingArrowsInListView) { PostVotingTile( @@ -1347,9 +1362,9 @@ fun PostListingList( } Column( modifier = - Modifier - .weight(1f) - .clickable { onPostClick(postView) }, + Modifier + .weight(1f) + .clickable { onPostClick(postView) }, verticalArrangement = Arrangement.spacedBy(SMALL_PADDING), ) { PostName(postView = postView, showIfRead = showIfRead) @@ -1406,10 +1421,10 @@ fun PostListingList( } Text( text = - stringResource( - R.string.post_listing_comments_count, - postView.counts.comments, - ), + stringResource( + R.string.post_listing_comments_count, + postView.counts.comments, + ), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onBackground.muted, ) @@ -1497,14 +1512,14 @@ private fun ThumbnailTile( painter = painterResource(id = R.drawable.triangle), contentDescription = null, modifier = - Modifier - .size(THUMBNAIL_CARET_SIZE) - .align(Alignment.BottomEnd), + Modifier + .size(THUMBNAIL_CARET_SIZE) + .align(Alignment.BottomEnd), tint = - when (postType) { - PostType.Video -> MaterialTheme.jerboaColorScheme.videoHighlight - else -> MaterialTheme.jerboaColorScheme.imageHighlight - }, + when (postType) { + PostType.Video -> MaterialTheme.jerboaColorScheme.videoHighlight + else -> MaterialTheme.jerboaColorScheme.imageHighlight + }, ) } } @@ -1612,10 +1627,10 @@ fun PostListingCard( ) { Column( modifier = - Modifier - .padding(vertical = MEDIUM_PADDING) - .clickable { onPostClick(postView) } - .testTag("jerboa:post"), + Modifier + .padding(vertical = MEDIUM_PADDING) + .clickable { onPostClick(postView) } + .testTag("jerboa:post"), // see https://stackoverflow.com/questions/77010371/prevent-popup-from-adding-padding-in-a-column-with-arrangement-spacedbylarge-p // verticalArrangement = Arrangement.spacedBy(LARGE_PADDING), ) { @@ -1699,9 +1714,9 @@ fun MetadataCard(post: Post) { OutlinedCard( shape = MaterialTheme.shapes.medium, modifier = - Modifier - .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) - .fillMaxWidth(), + Modifier + .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) + .fillMaxWidth(), content = { Column( modifier = Modifier.padding(MEDIUM_PADDING), diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt index 60be3a843..d532a51d6 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt @@ -28,6 +28,7 @@ import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount import com.jerboa.feat.SwipeToActionPreset import com.jerboa.isScrolledToEnd +import com.jerboa.model.ReplyItem import com.jerboa.rememberJerboaAppState import com.jerboa.ui.components.common.RetryLoadingPosts import com.jerboa.ui.components.common.simpleVerticalScrollbar @@ -51,6 +52,7 @@ fun PostListings( onDownvoteClick: (postView: PostView) -> Unit, onPostClick: (postView: PostView) -> Unit, onSaveClick: (postView: PostView) -> Unit, + onReplyClick: (postView: PostView) -> Unit, onEditPostClick: (postView: PostView) -> Unit, onDeletePostClick: (postView: PostView) -> Unit, onReportClick: (postView: PostView) -> Unit, @@ -108,6 +110,7 @@ fun PostListings( usePrivateTabs = usePrivateTabs, onUpvoteClick = onUpvoteClick, onDownvoteClick = onDownvoteClick, + onReplyClick = onReplyClick, onPostClick = onPostClick, onSaveClick = onSaveClick, onCommunityClick = onCommunityClick, @@ -210,5 +213,6 @@ fun PreviewPostListings() { postActionbarMode = 0, showPostAppendRetry = false, swipeToActionPreset = SwipeToActionPreset.DEFAULT, + onReplyClick = {} ) } diff --git a/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt b/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt index f5a15489b..0bf6646e3 100644 --- a/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/settings/lookandfeel/LookAndFeelActivity.kt @@ -45,6 +45,7 @@ import com.jerboa.feat.BackConfirmationMode import com.jerboa.feat.BlurTypes import com.jerboa.feat.PostActionbarMode import com.jerboa.feat.PostNavigationGestureMode +import com.jerboa.feat.SwipeToActionPreset import com.jerboa.getLangPreferenceDropdownEntries import com.jerboa.matchLocale import com.jerboa.model.AppSettingsViewModel @@ -305,6 +306,18 @@ fun LookAndFeelActivity( items = BlurTypes.entries.map { stringResource(it.resId) }, onItemSelected = { _, _ -> updateAppSettings() }, ) + SettingsListDropdown( + state = swipeToActionPreset, + icon = { + Icon( + imageVector = Icons.Outlined.Swipe, + contentDescription = null, + ) + }, + title = { Text(stringResource(id = R.string.swipe_to_action_presets)) }, + items = SwipeToActionPreset.entries.map { stringResource(it.resId) }, + onItemSelected = { _, _ -> updateAppSettings() }, + ) SettingsCheckbox( state = showBottomNavState, title = { From b5c0222c5a7d61d4ff4d8b69e101b8bc99ae9d28 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Sun, 4 Feb 2024 21:02:59 +0300 Subject: [PATCH 15/19] Fix formatting --- .../ui/components/comment/CommentNode.kt | 6 +- .../ui/components/common/SwipeToAction.kt | 54 +++--- .../jerboa/ui/components/post/PostListing.kt | 164 +++++++++--------- .../jerboa/ui/components/post/PostListings.kt | 3 +- 4 files changed, 118 insertions(+), 109 deletions(-) diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index f00f24645..4c9c3ec37 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -58,8 +58,6 @@ import com.jerboa.datatypes.sampleReplyCommentView import com.jerboa.datatypes.sampleSecondReplyCommentView import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount -import com.jerboa.db.entity.isAnon -import com.jerboa.db.entity.isReady import com.jerboa.feat.InstantScores import com.jerboa.feat.SwipeToActionPreset import com.jerboa.feat.SwipeToActionType @@ -268,9 +266,9 @@ fun LazyListScope.commentNodeItem( val swipeState = rememberSwipeActionState( swipeToActionPreset = swipeToActionPreset, - enableDownVotes = enableDownVotes + enableDownVotes = enableDownVotes, ) { - if(account.isReadyAndIfNotShowSimplifiedInfoToast(ctx)) { + if (account.isReadyAndIfNotShowSimplifiedInfoToast(ctx)) { when (it) { SwipeToActionType.Upvote -> { instantScores = diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index 2d4915c16..549cf5ef5 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -44,13 +44,17 @@ fun SwipeToAction( val leftActionsRanges = remember(swipeToActionPreset) { - SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions - .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }) + SwipeToActionType.getActionToRangeList( + swipeToActionPreset.leftActions + .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }, + ) } val rightActionsRanges = remember(swipeToActionPreset) { - SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions - .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }) + SwipeToActionType.getActionToRangeList( + swipeToActionPreset.rightActions + .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }, + ) } fun actionByState(state: SwipeToDismissBoxState): Pair, SwipeToActionType>? { @@ -95,24 +99,24 @@ fun SwipeToAction( ) Box( modifier = - Modifier - .fillMaxSize(), + Modifier + .fillMaxSize(), ) { Box( modifier = - Modifier - .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) - .fillMaxHeight() - .background(color = color) - .align( - if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) Alignment.TopEnd else Alignment.TopStart, - ), + Modifier + .fillMaxWidth(if (swipeState.progress != 1f) swipeState.progress else 0f) + .fillMaxHeight() + .background(color = color) + .align( + if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) Alignment.TopEnd else Alignment.TopStart, + ), contentAlignment = - if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) { - Alignment.CenterStart - } else { - Alignment.CenterEnd - }, + if (swipeState.targetValue == SwipeToDismissBoxValue.EndToStart) { + Alignment.CenterStart + } else { + Alignment.CenterEnd + }, ) { val tint = Color.White val modifier = @@ -141,7 +145,7 @@ fun SwipeToAction( fun rememberSwipeActionState( swipeToActionPreset: SwipeToActionPreset, enableDownVotes: Boolean = true, - onAction: (action: SwipeToActionType) -> Unit + onAction: (action: SwipeToActionType) -> Unit, ): SwipeToDismissBoxState { /* This hacky solution is required because confirmValueChange lambda doesn't pass progress state @@ -149,13 +153,17 @@ fun rememberSwipeActionState( */ val leftActionsRanges = remember(swipeToActionPreset) { - SwipeToActionType.getActionToRangeList(swipeToActionPreset.leftActions - .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }) + SwipeToActionType.getActionToRangeList( + swipeToActionPreset.leftActions + .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }, + ) } val rightActionsRanges = remember(swipeToActionPreset) { - SwipeToActionType.getActionToRangeList(swipeToActionPreset.rightActions - .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }) + SwipeToActionType.getActionToRangeList( + swipeToActionPreset.rightActions + .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }, + ) } val progressState = remember { mutableFloatStateOf(1.0f) } val dismissState = diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt index 3c92b9f5b..1a9595f25 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt @@ -359,10 +359,10 @@ fun PostTitleAndImageLink( Column( modifier = - Modifier.padding( - vertical = MEDIUM_PADDING, - horizontal = MEDIUM_PADDING, - ), + Modifier.padding( + vertical = MEDIUM_PADDING, + horizontal = MEDIUM_PADDING, + ), ) { // Title of the post PostName( @@ -375,11 +375,11 @@ fun PostTitleAndImageLink( url = url, blur = blurNSFW.toEnum().needBlur(postView), modifier = - Modifier - .combinedClickable( - onClick = { appState.openImageViewer(url) }, - onLongClick = { appState.showLinkPopup(url) }, - ), + Modifier + .combinedClickable( + onClick = { appState.openImageViewer(url) }, + onLongClick = { appState.showLinkPopup(url) }, + ), ) } @@ -473,15 +473,15 @@ fun PostBody( colors = CARD_COLORS, shape = MaterialTheme.shapes.medium, modifier = - Modifier - .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) - .fillMaxWidth(), + Modifier + .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) + .fillMaxWidth(), content = { if (fullBody) { Column( modifier = - Modifier - .padding(MEDIUM_PADDING), + Modifier + .padding(MEDIUM_PADDING), ) { if (viewSource) { SelectionContainer { @@ -648,9 +648,9 @@ fun PostFooterLine( horizontalArrangement = horizontalArrangement, verticalAlignment = Alignment.Bottom, modifier = - modifier - .fillMaxWidth() - .padding(bottom = SMALL_PADDING), + modifier + .fillMaxWidth() + .padding(bottom = SMALL_PADDING), ) { // Right handside shows the comments on the left side if (postActionbar == PostActionbarMode.RightHandShort) { @@ -700,24 +700,24 @@ fun PostFooterLine( } ActionBarButton( icon = - if (postView.saved) { - Icons.Filled.Bookmark - } else { - Icons.Outlined.BookmarkBorder - }, + if (postView.saved) { + Icons.Filled.Bookmark + } else { + Icons.Outlined.BookmarkBorder + }, contentDescription = - if (postView.saved) { - stringResource(R.string.removeBookmark) - } else { - stringResource(R.string.addBookmark) - }, + if (postView.saved) { + stringResource(R.string.removeBookmark) + } else { + stringResource(R.string.addBookmark) + }, onClick = { onSaveClick(postView) }, contentColor = - if (postView.saved) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.onBackground.muted - }, + if (postView.saved) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.onBackground.muted + }, account = account, ) ActionBarButton( @@ -726,10 +726,14 @@ fun PostFooterLine( account = account, onClick = { showMoreOptions = !showMoreOptions }, requiresAccount = false, - modifier = if (postActionbar == PostActionbarMode.LeftHandShort) Modifier.weight( - 1F, - true - ) else Modifier, + modifier = if (postActionbar == PostActionbarMode.LeftHandShort) { + Modifier.weight( + 1F, + true, + ) + } else { + Modifier + }, ) if (postActionbar == PostActionbarMode.LeftHandShort) { @@ -1081,22 +1085,22 @@ fun PostListing( val ctx = LocalContext.current // This stores vote data var instantScores by - remember { - mutableStateOf( - InstantScores( - myVote = postView.my_vote, - score = postView.counts.score, - upvotes = postView.counts.upvotes, - downvotes = postView.counts.downvotes, - ), - ) - } + remember { + mutableStateOf( + InstantScores( + myVote = postView.my_vote, + score = postView.counts.score, + upvotes = postView.counts.upvotes, + downvotes = postView.counts.downvotes, + ), + ) + } var viewSource by remember { mutableStateOf(false) } val swipeState = rememberSwipeActionState( swipeToActionPreset = swipeToActionPreset, - enableDownVotes = enableDownVotes + enableDownVotes = enableDownVotes, ) { if (account.isReadyAndIfNotShowSimplifiedInfoToast(ctx)) { when (it) { @@ -1276,9 +1280,9 @@ fun PostVotingTile( Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = - Modifier - .fillMaxHeight() - .padding(end = MEDIUM_PADDING), + Modifier + .fillMaxHeight() + .padding(end = MEDIUM_PADDING), ) { VoteGeneric( myVote = instantScores.myVote, @@ -1336,19 +1340,19 @@ fun PostListingList( ) { Column( modifier = - Modifier - .padding( - horizontal = MEDIUM_PADDING, - vertical = MEDIUM_PADDING, - ) - .testTag("jerboa:post"), + Modifier + .padding( + horizontal = MEDIUM_PADDING, + vertical = MEDIUM_PADDING, + ) + .testTag("jerboa:post"), ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = - Arrangement.spacedBy( - SMALL_PADDING, - ), + Arrangement.spacedBy( + SMALL_PADDING, + ), ) { if (showVotingArrowsInListView) { PostVotingTile( @@ -1362,9 +1366,9 @@ fun PostListingList( } Column( modifier = - Modifier - .weight(1f) - .clickable { onPostClick(postView) }, + Modifier + .weight(1f) + .clickable { onPostClick(postView) }, verticalArrangement = Arrangement.spacedBy(SMALL_PADDING), ) { PostName(postView = postView, showIfRead = showIfRead) @@ -1421,10 +1425,10 @@ fun PostListingList( } Text( text = - stringResource( - R.string.post_listing_comments_count, - postView.counts.comments, - ), + stringResource( + R.string.post_listing_comments_count, + postView.counts.comments, + ), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onBackground.muted, ) @@ -1512,14 +1516,14 @@ private fun ThumbnailTile( painter = painterResource(id = R.drawable.triangle), contentDescription = null, modifier = - Modifier - .size(THUMBNAIL_CARET_SIZE) - .align(Alignment.BottomEnd), + Modifier + .size(THUMBNAIL_CARET_SIZE) + .align(Alignment.BottomEnd), tint = - when (postType) { - PostType.Video -> MaterialTheme.jerboaColorScheme.videoHighlight - else -> MaterialTheme.jerboaColorScheme.imageHighlight - }, + when (postType) { + PostType.Video -> MaterialTheme.jerboaColorScheme.videoHighlight + else -> MaterialTheme.jerboaColorScheme.imageHighlight + }, ) } } @@ -1627,10 +1631,10 @@ fun PostListingCard( ) { Column( modifier = - Modifier - .padding(vertical = MEDIUM_PADDING) - .clickable { onPostClick(postView) } - .testTag("jerboa:post"), + Modifier + .padding(vertical = MEDIUM_PADDING) + .clickable { onPostClick(postView) } + .testTag("jerboa:post"), // see https://stackoverflow.com/questions/77010371/prevent-popup-from-adding-padding-in-a-column-with-arrangement-spacedbylarge-p // verticalArrangement = Arrangement.spacedBy(LARGE_PADDING), ) { @@ -1714,9 +1718,9 @@ fun MetadataCard(post: Post) { OutlinedCard( shape = MaterialTheme.shapes.medium, modifier = - Modifier - .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) - .fillMaxWidth(), + Modifier + .padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING) + .fillMaxWidth(), content = { Column( modifier = Modifier.padding(MEDIUM_PADDING), diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt index d532a51d6..2e8f0db99 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt @@ -28,7 +28,6 @@ import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount import com.jerboa.feat.SwipeToActionPreset import com.jerboa.isScrolledToEnd -import com.jerboa.model.ReplyItem import com.jerboa.rememberJerboaAppState import com.jerboa.ui.components.common.RetryLoadingPosts import com.jerboa.ui.components.common.simpleVerticalScrollbar @@ -213,6 +212,6 @@ fun PreviewPostListings() { postActionbarMode = 0, showPostAppendRetry = false, swipeToActionPreset = SwipeToActionPreset.DEFAULT, - onReplyClick = {} + onReplyClick = {}, ) } From 8ac5f474e3f4f3cbcda2a7a093f1ebbc3c02dfc3 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Mon, 5 Feb 2024 01:04:49 +0300 Subject: [PATCH 16/19] Remove default param for enableDownVotes in SwipeToAction --- .../java/com/jerboa/ui/components/common/SwipeToAction.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index 549cf5ef5..a1ab47def 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -36,7 +36,7 @@ import com.jerboa.feat.SwipeToActionType.Companion.START_THRESHOLD @ExperimentalMaterial3Api fun SwipeToAction( swipeToActionPreset: SwipeToActionPreset, - enableDownVotes: Boolean = true, + enableDownVotes: Boolean, swipeableContent: @Composable RowScope.() -> Unit, swipeState: SwipeToDismissBoxState, ) { @@ -144,7 +144,7 @@ fun SwipeToAction( @Composable fun rememberSwipeActionState( swipeToActionPreset: SwipeToActionPreset, - enableDownVotes: Boolean = true, + enableDownVotes: Boolean, onAction: (action: SwipeToActionType) -> Unit, ): SwipeToDismissBoxState { /* From 707990a9f844620480409234c203ac5152611b84 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Mon, 5 Feb 2024 13:36:10 +0300 Subject: [PATCH 17/19] Fix colors for swipe actions --- app/src/main/java/com/jerboa/feat/SwipeToAction.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt index f2d6aca35..54b2fd577 100644 --- a/app/src/main/java/com/jerboa/feat/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/feat/SwipeToAction.kt @@ -44,10 +44,10 @@ enum class SwipeToActionType { @Composable fun getActionColor(): Color { return when (this) { - Upvote -> MaterialTheme.colorScheme.primary - Downvote -> MaterialTheme.colorScheme.tertiary - Reply -> MaterialTheme.colorScheme.onPrimary - Save -> MaterialTheme.colorScheme.onTertiary + Upvote -> MaterialTheme.colorScheme.secondary + Downvote -> MaterialTheme.colorScheme.error + Reply -> MaterialTheme.colorScheme.inversePrimary + Save -> MaterialTheme.colorScheme.primary } } } From b936b56b7a85e9aac08f4f14d9cbec5cd789a195 Mon Sep 17 00:00:00 2001 From: snow4dv Date: Mon, 5 Feb 2024 18:01:53 +0300 Subject: [PATCH 18/19] Fixed lambda caching in rememberSwipeActionState --- .../ui/components/comment/CommentNode.kt | 1 + .../ui/components/common/SwipeToAction.kt | 70 ++++++++++++------- .../jerboa/ui/components/post/PostListing.kt | 48 +++++++------ 3 files changed, 71 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index 4c9c3ec37..436f2ee9b 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -267,6 +267,7 @@ fun LazyListScope.commentNodeItem( val swipeState = rememberSwipeActionState( swipeToActionPreset = swipeToActionPreset, enableDownVotes = enableDownVotes, + rememberKey = commentView ) { if (account.isReadyAndIfNotShowSimplifiedInfoToast(ctx)) { when (it) { diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index a1ab47def..9c145d3d5 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -22,10 +22,12 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.unit.dp import com.jerboa.feat.SwipeToActionPreset @@ -43,14 +45,14 @@ fun SwipeToAction( val haptic = LocalHapticFeedback.current val leftActionsRanges = - remember(swipeToActionPreset) { + remember(swipeToActionPreset, enableDownVotes) { SwipeToActionType.getActionToRangeList( swipeToActionPreset.leftActions .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }, ) } val rightActionsRanges = - remember(swipeToActionPreset) { + remember(swipeToActionPreset, enableDownVotes) { SwipeToActionType.getActionToRangeList( swipeToActionPreset.rightActions .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }, @@ -145,51 +147,65 @@ fun SwipeToAction( fun rememberSwipeActionState( swipeToActionPreset: SwipeToActionPreset, enableDownVotes: Boolean, + rememberKey: Any? = Unit, onAction: (action: SwipeToActionType) -> Unit, ): SwipeToDismissBoxState { /* This hacky solution is required because confirmValueChange lambda doesn't pass progress state They didn't fix it with new SwipeToDismissBoxState */ + val density = LocalDensity.current + val leftActionsRanges = - remember(swipeToActionPreset) { + remember(swipeToActionPreset, enableDownVotes) { SwipeToActionType.getActionToRangeList( swipeToActionPreset.leftActions .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }, ) } val rightActionsRanges = - remember(swipeToActionPreset) { + remember(swipeToActionPreset, enableDownVotes) { SwipeToActionType.getActionToRangeList( swipeToActionPreset.rightActions .filter { !(it == SwipeToActionType.Downvote && !enableDownVotes) }, ) } + val progressState = remember { mutableFloatStateOf(1.0f) } - val dismissState = - rememberSwipeToDismissBoxState( - positionalThreshold = { totalDistance -> totalDistance * START_THRESHOLD }, - confirmValueChange = { dismissValue -> - val action = - when (dismissValue) { - SwipeToDismissBoxValue.StartToEnd -> { - leftActionsRanges.findLast { progressState.floatValue in it.first } - } - - SwipeToDismissBoxValue.EndToStart -> { - rightActionsRanges.findLast { progressState.floatValue in it.first } - } - - else -> { - null - } - } - action?.second?.let { actionType -> - onAction(actionType) + + val confirmValueChange: (SwipeToDismissBoxValue) -> Boolean = { dismissValue -> + val action = + when (dismissValue) { + SwipeToDismissBoxValue.StartToEnd -> { + leftActionsRanges.findLast { progressState.floatValue in it.first } + } + + SwipeToDismissBoxValue.EndToStart -> { + rightActionsRanges.findLast { progressState.floatValue in it.first } + } + + else -> { + null } - false // do not dismiss - }, - ) + } + action?.second?.let { actionType -> + onAction(actionType) + } + false // do not dismiss + } + + val positionalThreshold: (totalDistance: Float) -> Float = { totalDistance -> totalDistance * START_THRESHOLD } + + val dismissState = rememberSaveable( + saver = SwipeToDismissBoxState.Saver( + confirmValueChange = confirmValueChange, + density = density, + positionalThreshold = { totalDistance -> totalDistance * START_THRESHOLD } + ), + inputs = arrayOf(rememberKey) + ) { + SwipeToDismissBoxState(SwipeToDismissBoxValue.Settled, density, confirmValueChange, positionalThreshold) + } progressState.floatValue = dismissState.progress return dismissState } diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt index 1a9595f25..03f7809b3 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt @@ -1098,35 +1098,41 @@ fun PostListing( var viewSource by remember { mutableStateOf(false) } - val swipeState = rememberSwipeActionState( - swipeToActionPreset = swipeToActionPreset, - enableDownVotes = enableDownVotes, - ) { - if (account.isReadyAndIfNotShowSimplifiedInfoToast(ctx)) { - when (it) { - SwipeToActionType.Upvote -> { - instantScores = - instantScores.update(VoteType.Upvote) - onUpvoteClick(postView) - } + val swipeAction: (action: SwipeToActionType) -> Unit = remember(postView) { + { + if (account.isReadyAndIfNotShowSimplifiedInfoToast(ctx)) { + when (it) { + SwipeToActionType.Upvote -> { + instantScores = + instantScores.update(VoteType.Upvote) + onUpvoteClick(postView) + } - SwipeToActionType.Downvote -> { - instantScores = - instantScores.update(VoteType.Downvote) - onDownvoteClick(postView) - } + SwipeToActionType.Downvote -> { + instantScores = + instantScores.update(VoteType.Downvote) + onDownvoteClick(postView) + } - SwipeToActionType.Reply -> { - onReplyClick(postView) - } + SwipeToActionType.Reply -> { + onReplyClick(postView) + } - SwipeToActionType.Save -> { - onSaveClick(postView) + SwipeToActionType.Save -> { + onSaveClick(postView) + } } } } } + val swipeState = rememberSwipeActionState( + swipeToActionPreset = swipeToActionPreset, + enableDownVotes = enableDownVotes, + onAction = swipeAction, + rememberKey = postView + ) + val swipeableContent: @Composable RowScope.() -> Unit = { Row { when (postViewMode) { From eed2dfdc36a77013277fd21f97e52f68886fed7a Mon Sep 17 00:00:00 2001 From: snow4dv Date: Mon, 5 Feb 2024 18:51:52 +0300 Subject: [PATCH 19/19] Format kotlin --- .../ui/components/comment/CommentNode.kt | 120 +++++++++--------- .../ui/components/common/SwipeToAction.kt | 5 +- .../jerboa/ui/components/post/PostListing.kt | 2 +- 3 files changed, 62 insertions(+), 65 deletions(-) diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index 9a43c4d88..81f03a0c0 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -238,7 +238,7 @@ fun LazyListScope.commentNodeItem( val showMoreChildren = isExpanded(commentId) && node.children.isEmpty() && - commentView.counts.child_count > 0 && !isFlat + commentView.counts.child_count > 0 && !isFlat increaseLazyListIndexTracker() // TODO Needs a contentType @@ -253,21 +253,21 @@ fun LazyListScope.commentNodeItem( val ctx = LocalContext.current var instantScores by - remember { - mutableStateOf( - InstantScores( - myVote = commentView.my_vote, - score = commentView.counts.score, - upvotes = commentView.counts.upvotes, - downvotes = commentView.counts.downvotes, - ), - ) - } + remember { + mutableStateOf( + InstantScores( + myVote = commentView.my_vote, + score = commentView.counts.score, + upvotes = commentView.counts.upvotes, + downvotes = commentView.counts.downvotes, + ), + ) + } val swipeState = rememberSwipeActionState( swipeToActionPreset = swipeToActionPreset, enableDownVotes = enableDownVotes, - rememberKey = commentView + rememberKey = commentView, ) { if (account.isReadyAndIfNotShowSimplifiedInfoToast(ctx)) { when (it) { @@ -291,7 +291,6 @@ fun LazyListScope.commentNodeItem( } } - val swipeableContent: @Composable RowScope.() -> Unit = { AnimatedVisibility( visible = !isCollapsedByParent, @@ -300,10 +299,10 @@ fun LazyListScope.commentNodeItem( ) { Column( modifier = - Modifier - .padding( - start = offset, - ), + Modifier + .padding( + start = offset, + ), ) { Column( modifier = Modifier.border(start = border), @@ -311,10 +310,10 @@ fun LazyListScope.commentNodeItem( HorizontalDivider(modifier = Modifier.padding(start = if (node.depth == 0) 0.dp else border.strokeWidth)) Column( modifier = - Modifier.padding( - start = offset2, - end = MEDIUM_PADDING, - ), + Modifier.padding( + start = offset2, + end = MEDIUM_PADDING, + ), ) { if (showPostAndCommunityContext) { PostAndCommunityContextHeader( @@ -482,7 +481,7 @@ fun LazyListScope.commentNodeItem( showScores = showScores, admins = admins, moderators = moderators, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } @@ -550,7 +549,6 @@ fun LazyListScope.missingCommentNodeItem( val borderColor = calculateBorderColor(backgroundColor, node.depth) val border = Border(SMALL_PADDING, borderColor) - AnimatedVisibility( visible = !isCollapsedByParent, enter = expandVertically(), @@ -558,10 +556,10 @@ fun LazyListScope.missingCommentNodeItem( ) { Column( modifier = - Modifier - .padding( - start = offset, - ), + Modifier + .padding( + start = offset, + ), ) { Column( modifier = Modifier.border(start = border), @@ -569,10 +567,10 @@ fun LazyListScope.missingCommentNodeItem( HorizontalDivider(modifier = Modifier.padding(start = if (node.depth == 0) 0.dp else border.strokeWidth)) Column( modifier = - Modifier.padding( - start = offset2, - end = MEDIUM_PADDING, - ), + Modifier.padding( + start = offset2, + end = MEDIUM_PADDING, + ), ) { AnimatedVisibility( visible = isExpanded(commentId) || showCollapsedCommentContent, @@ -633,7 +631,7 @@ fun LazyListScope.missingCommentNodeItem( showAvatar = showAvatar, blurNSFW = blurNSFW, showScores = showScores, - swipeToActionPreset = swipeToActionPreset + swipeToActionPreset = swipeToActionPreset, ) } @@ -665,10 +663,10 @@ private fun ShowMoreChildrenNode( ) { Column( modifier = - Modifier - .padding( - start = offset, - ), + Modifier + .padding( + start = offset, + ), ) { HorizontalDivider() Column( @@ -812,15 +810,15 @@ fun CommentFooterLine( Row( horizontalArrangement = Arrangement.End, modifier = - Modifier - .fillMaxWidth() - .combinedClickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onClick, - onLongClick = onLongClick, - ) - .padding(top = LARGE_PADDING, bottom = SMALL_PADDING), + Modifier + .fillMaxWidth() + .combinedClickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = onClick, + onLongClick = onLongClick, + ) + .padding(top = LARGE_PADDING, bottom = SMALL_PADDING), ) { Row( horizontalArrangement = Arrangement.spacedBy(XXL_PADDING), @@ -851,24 +849,24 @@ fun CommentFooterLine( ) ActionBarButton( icon = - if (commentView.saved) { - Icons.Filled.Bookmark - } else { - Icons.Outlined.BookmarkBorder - }, + if (commentView.saved) { + Icons.Filled.Bookmark + } else { + Icons.Outlined.BookmarkBorder + }, contentDescription = - if (commentView.saved) { - stringResource(R.string.removeBookmark) - } else { - stringResource(R.string.addBookmark) - }, + if (commentView.saved) { + stringResource(R.string.removeBookmark) + } else { + stringResource(R.string.addBookmark) + }, onClick = { onSaveClick(commentView) }, contentColor = - if (commentView.saved) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.onBackground.muted - }, + if (commentView.saved) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.onBackground.muted + }, account = account, ) ActionBarButton( @@ -933,7 +931,7 @@ fun CommentNodesPreview() { blurNSFW = 1, account = AnonAccount, showScores = true, - swipeToActionPreset = SwipeToActionPreset.DEFAULT + swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt index 9c145d3d5..990b8daef 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/SwipeToAction.kt @@ -16,7 +16,6 @@ import androidx.compose.material3.Icon import androidx.compose.material3.SwipeToDismissBox import androidx.compose.material3.SwipeToDismissBoxState import androidx.compose.material3.SwipeToDismissBoxValue -import androidx.compose.material3.rememberSwipeToDismissBoxState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf @@ -200,9 +199,9 @@ fun rememberSwipeActionState( saver = SwipeToDismissBoxState.Saver( confirmValueChange = confirmValueChange, density = density, - positionalThreshold = { totalDistance -> totalDistance * START_THRESHOLD } + positionalThreshold = { totalDistance -> totalDistance * START_THRESHOLD }, ), - inputs = arrayOf(rememberKey) + inputs = arrayOf(rememberKey), ) { SwipeToDismissBoxState(SwipeToDismissBoxValue.Settled, density, confirmValueChange, positionalThreshold) } diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt index fd906c2f2..d659d8555 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt @@ -1137,7 +1137,7 @@ fun PostListing( swipeToActionPreset = swipeToActionPreset, enableDownVotes = enableDownVotes, onAction = swipeAction, - rememberKey = postView + rememberKey = postView, ) val swipeableContent: @Composable RowScope.() -> Unit = {