Skip to content

Commit

Permalink
feat(ui): swipe to star/unstar, swipe to unread (Ashinch#594)
Browse files Browse the repository at this point in the history
* feat(ui): swipe to star & unstar

* feat(ui): swipe to unread

* feat(ui): add haptic feedback to swipe gesture

* fix(ui): disable swipe gestures when scroll in progress

* feat(ui): configure swipe gestures

* fix(ui): workaround for swipe animation & remove text label

* fix(ui): app initialize with toggle starred
  • Loading branch information
JunkFood02 authored Feb 11, 2024
1 parent c21e22d commit 8c11757
Show file tree
Hide file tree
Showing 11 changed files with 998 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ fun Preferences.toSettings(): Settings {
// Interaction
initialPage = InitialPagePreference.fromPreferences(this),
initialFilter = InitialFilterPreference.fromPreferences(this),
swipeStartAction = SwipeStartActionPreference.fromPreferences(this),
swipeEndAction = SwipeEndActionPreference.fromPreferences(this),
openLink = OpenLinkPreference.fromPreferences(this),
openLinkSpecificBrowser = OpenLinkSpecificBrowserPreference.fromPreferences(this),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ data class Settings(
// Interaction
val initialPage: InitialPagePreference = InitialPagePreference.default,
val initialFilter: InitialFilterPreference = InitialFilterPreference.default,
val swipeStartAction: SwipeStartActionPreference = SwipeStartActionPreference.default,
val swipeEndAction: SwipeEndActionPreference = SwipeEndActionPreference.default,
val openLink: OpenLinkPreference = OpenLinkPreference.default,
val openLinkSpecificBrowser: OpenLinkSpecificBrowserPreference = OpenLinkSpecificBrowserPreference.default,

Expand Down Expand Up @@ -177,6 +179,8 @@ val LocalReadingImageMaximize =
val LocalInitialPage = compositionLocalOf<InitialPagePreference> { InitialPagePreference.default }
val LocalInitialFilter =
compositionLocalOf<InitialFilterPreference> { InitialFilterPreference.default }
val LocalArticleListSwipeEndAction = compositionLocalOf { SwipeEndActionPreference.default }
val LocalArticleListSwipeStartAction = compositionLocalOf { SwipeStartActionPreference.default }
val LocalOpenLink =
compositionLocalOf<OpenLinkPreference> { OpenLinkPreference.default }
val LocalOpenLinkSpecificBrowser =
Expand Down Expand Up @@ -263,6 +267,8 @@ fun SettingsProvider(
// Interaction
LocalInitialPage provides settings.initialPage,
LocalInitialFilter provides settings.initialFilter,
LocalArticleListSwipeStartAction provides settings.swipeStartAction,
LocalArticleListSwipeEndAction provides settings.swipeEndAction,
LocalOpenLink provides settings.openLink,
LocalOpenLinkSpecificBrowser provides settings.openLinkSpecificBrowser,

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package me.ash.reader.infrastructure.preference

import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import me.ash.reader.R
import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put

data object SwipeGestureActions {
const val None = 0
const val ToggleRead = 1
const val ToggleStarred = 2
}

sealed class SwipeEndActionPreference(val action: Int) : Preference() {
override fun put(context: Context, scope: CoroutineScope) {
scope.launch {
context.dataStore.put(
DataStoreKeys.SwipeEndAction, action
)
}
}

data object None : SwipeEndActionPreference(SwipeGestureActions.None)
data object ToggleRead : SwipeEndActionPreference(SwipeGestureActions.ToggleRead)
data object ToggleStarred :
SwipeEndActionPreference(SwipeGestureActions.ToggleStarred)

val desc: String
@Composable get() = when (this) {
None -> stringResource(id = R.string.none)
ToggleRead -> stringResource(id = R.string.toggle_read)
ToggleStarred -> stringResource(id = R.string.toggle_starred)
}

companion object {
val default: SwipeEndActionPreference = ToggleRead
val values = listOf(
None,
ToggleRead,
ToggleStarred
)

fun fromPreferences(preferences: Preferences): SwipeEndActionPreference {
return when (preferences[DataStoreKeys.SwipeEndAction.key]) {
SwipeGestureActions.None -> None
SwipeGestureActions.ToggleRead -> ToggleRead
SwipeGestureActions.ToggleStarred -> ToggleStarred
else -> default
}
}
}
}

sealed class SwipeStartActionPreference(val action: Int) : Preference() {
override fun put(context: Context, scope: CoroutineScope) {
scope.launch {
context.dataStore.put(
DataStoreKeys.SwipeStartAction, action
)
}
}

data object None : SwipeStartActionPreference(SwipeGestureActions.None)
data object ToggleRead : SwipeStartActionPreference(SwipeGestureActions.ToggleRead)
data object ToggleStarred :
SwipeStartActionPreference(SwipeGestureActions.ToggleStarred)

val desc: String
@Composable get() = when (this) {
None -> stringResource(id = R.string.none)
ToggleRead -> stringResource(id = R.string.toggle_read)
ToggleStarred -> stringResource(id = R.string.toggle_starred)
}

companion object {
val default: SwipeStartActionPreference = ToggleStarred
val values = listOf(
None,
ToggleRead,
ToggleStarred
)

fun fromPreferences(preferences: Preferences): SwipeStartActionPreference {
return when (preferences[DataStoreKeys.SwipeStartAction.key]) {
SwipeGestureActions.None -> None
SwipeGestureActions.ToggleRead -> ToggleRead
SwipeGestureActions.ToggleStarred -> ToggleStarred
else -> default
}
}
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/me/ash/reader/ui/ext/DataStoreExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,18 @@ sealed class DataStoreKeys<T> {
get() = intPreferencesKey("initialFilter")
}

data object SwipeStartAction : DataStoreKeys<Int>() {

override val key: Preferences.Key<Int>
get() = intPreferencesKey("swipeStartAction")
}

data object SwipeEndAction : DataStoreKeys<Int>() {

override val key: Preferences.Key<Int>
get() = intPreferencesKey("swipeEndAction")
}

object OpenLink : DataStoreKeys<Int>() {

override val key: Preferences.Key<Int>
Expand Down
Loading

0 comments on commit 8c11757

Please sign in to comment.