Skip to content

Commit

Permalink
Add star and read to long press (#442)
Browse files Browse the repository at this point in the history
  • Loading branch information
jocmp authored Oct 20, 2024
1 parent e743cf3 commit b5788ec
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ fun ArticleRow(

ArticleActionMenu(
expanded = isArticleMenuOpen,
articleID = article.id,
article = article,
onMarkAllRead = {
setArticleMenuOpen(false)
onMarkAllRead(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,24 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import com.jocmp.capy.MarkRead
import com.jocmp.capy.MarkRead.After
import com.jocmp.capy.MarkRead.Before
import com.capyreader.app.R
import com.capyreader.app.ui.articles.LocalArticleActions
import com.capyreader.app.ui.components.ArticleAction
import com.capyreader.app.ui.components.readAction
import com.capyreader.app.ui.components.starAction
import com.capyreader.app.ui.fixtures.ArticleSample
import com.jocmp.capy.Article

@Composable
fun ArticleActionMenu(
expanded: Boolean,
articleID: String,
article: Article,
onMarkAllRead: (range: MarkRead) -> Unit = {},
onDismissRequest: () -> Unit = {},
) {
Expand All @@ -27,6 +34,8 @@ fun ArticleActionMenu(
onDismissRequest = { onDismissRequest() },
offset = DpOffset(x = 4.dp, y = 0.dp)
) {
ToggleStarMenuItem(onDismissRequest, article)
ToggleReadMenuItem(onDismissRequest, article)
DropdownMenuItem(
leadingIcon = {
Icon(
Expand All @@ -35,7 +44,7 @@ fun ArticleActionMenu(
)
},
text = { Text(stringResource(R.string.article_actions_mark_after_as_read)) },
onClick = { onMarkAllRead(After(articleID)) },
onClick = { onMarkAllRead(After(article.id)) },
)
DropdownMenuItem(
leadingIcon = {
Expand All @@ -45,16 +54,51 @@ fun ArticleActionMenu(
)
},
text = { Text(stringResource(R.string.article_actions_mark_below_as_read)) },
onClick = { onMarkAllRead(Before(articleID)) },
onClick = { onMarkAllRead(Before(article.id)) },
)
}
}

@Composable
private fun ToggleReadMenuItem(onDismissRequest: () -> Unit, article: Article) {
val action = readAction(article, LocalArticleActions.current)

ToggleActionMenuItem(onDismissRequest, action)
}


@Composable
private fun ToggleStarMenuItem(onDismissRequest: () -> Unit, article: Article) {
val action = starAction(article, LocalArticleActions.current)

ToggleActionMenuItem(onDismissRequest, action)
}

@Composable
private fun ToggleActionMenuItem(
onDismissRequest: () -> Unit,
action: ArticleAction,
) {
DropdownMenuItem(
leadingIcon = {
Icon(
painterResource(action.icon),
contentDescription = null
)
},
text = { Text(stringResource(action.translationKey)) },
onClick = {
onDismissRequest()
action.commit()
},
)
}

@Preview
@Composable
private fun ArticleActionMenuPreview() {
private fun ArticleActionMenuPreview(@PreviewParameter(ArticleSample::class) article: Article) {
ArticleActionMenu(
expanded = true,
articleID = "1234"
article = article
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -50,7 +51,7 @@ fun ArticleRowSwipeBox(
.background(color)
) {
Icon(
action.icon,
painterResource(action.icon),
contentDescription = stringResource(id = action.translationKey),
modifier = Modifier
.padding(24.dp)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,47 +1,34 @@
package com.capyreader.app.ui.articles.list

import android.content.Context
import android.net.Uri
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.OpenInNew
import androidx.compose.material.icons.outlined.Circle
import androidx.compose.material.icons.rounded.Circle
import androidx.compose.material.icons.rounded.Star
import androidx.compose.material.icons.rounded.StarOutline
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.remember
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import com.capyreader.app.R
import com.capyreader.app.common.AppPreferences
import com.capyreader.app.common.asState
import com.capyreader.app.common.openLink
import com.capyreader.app.common.openLinkExternally
import com.capyreader.app.ui.articles.ArticleActions
import com.capyreader.app.ui.articles.LocalArticleActions
import com.capyreader.app.ui.articles.list.ArticleRowSwipeState.SwipeAction
import com.capyreader.app.ui.components.ArticleAction
import com.capyreader.app.ui.components.readAction
import com.capyreader.app.ui.components.starAction
import com.capyreader.app.ui.settings.panels.RowSwipeOption
import com.jocmp.capy.Article
import org.koin.compose.koinInject

internal data class ArticleRowSwipeState(
val state: SwipeToDismissBoxState,
val action: SwipeAction,
val action: ArticleAction,
val enableStart: Boolean,
val enableEnd: Boolean,
) {
val enabled = enableStart || enableEnd

data class SwipeAction(
val icon: ImageVector,
@StringRes val translationKey: Int,
val commit: () -> Unit,
)
}

@Composable
Expand Down Expand Up @@ -85,45 +72,9 @@ fun swipePreference(
}

private fun openExternally(context: Context, article: Article) =
SwipeAction(
Icons.AutoMirrored.Rounded.OpenInNew,
ArticleAction(
R.drawable.icon_open_in_new,
R.string.article_view_open_externally,
) {
context.openLinkExternally(article.url)
}

private fun starAction(article: Article, actions: ArticleActions): SwipeAction {
return when {
article.starred -> SwipeAction(
Icons.Rounded.StarOutline,
R.string.article_view_unstar,
) {
actions.unstar(article.id)
}

else -> SwipeAction(
Icons.Rounded.Star,
R.string.article_view_star,
) {
actions.star(article.id)
}
}
}

private fun readAction(article: Article, actions: ArticleActions): SwipeAction {
return when {
article.read -> SwipeAction(
Icons.Rounded.Circle,
R.string.article_view_mark_as_unread,
) {
actions.markUnread(article.id)
}

else -> SwipeAction(
Icons.Outlined.Circle,
R.string.article_view_mark_as_read,
) {
actions.markRead(article.id)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.capyreader.app.ui.components

import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Circle
import androidx.compose.material.icons.rounded.Circle
import androidx.compose.material.icons.rounded.Star
import androidx.compose.material.icons.rounded.StarOutline
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import com.capyreader.app.R
import com.capyreader.app.ui.articles.ArticleActions
import com.jocmp.capy.Article

data class ArticleAction(
@DrawableRes val icon: Int,
@StringRes val translationKey: Int,
val commit: () -> Unit,
)

fun readAction(article: Article, actions: ArticleActions) =
if (article.read) {
ArticleAction(
R.drawable.icon_circle_filled,
R.string.article_view_mark_as_unread,
) {
actions.markUnread(article.id)
}
} else {
ArticleAction(
R.drawable.icon_circle_outline,
R.string.article_view_mark_as_read,
) {
actions.markRead(article.id)
}
}

fun starAction(article: Article, actions: ArticleActions) =
if (article.starred) {
ArticleAction(
R.drawable.icon_star_outline,
R.string.article_view_unstar,
) {
actions.unstar(article.id)
}
} else {
ArticleAction(
R.drawable.icon_star_filled,
R.string.article_view_star,
) {
actions.star(article.id)
}
}
12 changes: 6 additions & 6 deletions app/src/main/res/drawable/icon_circle_filled.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="960"
android:viewportHeight="960">
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M480,880q-83,0 -156,-31.5T197,763q-54,-54 -85.5,-127T80,480q0,-83 31.5,-156T197,197q54,-54 127,-85.5T480,80q83,0 156,31.5T763,197q54,54 85.5,127T880,480q0,83 -31.5,156T763,763q-54,54 -127,85.5T480,880Z"/>
android:pathData="M12.001,19C11.033,19 10.123,18.816 9.271,18.449C8.419,18.081 7.678,17.583 7.048,16.953C6.418,16.323 5.919,15.582 5.551,14.731C5.184,13.879 5,12.969 5,12.001C5,11.033 5.184,10.123 5.551,9.271C5.919,8.419 6.417,7.678 7.047,7.048C7.677,6.418 8.418,5.919 9.269,5.551C10.121,5.184 11.031,5 11.999,5C12.967,5 13.877,5.184 14.729,5.551C15.581,5.919 16.322,6.417 16.952,7.047C17.582,7.677 18.081,8.418 18.449,9.269C18.816,10.121 19,11.031 19,11.999C19,12.967 18.816,13.877 18.449,14.729C18.081,15.581 17.583,16.322 16.953,16.952C16.323,17.582 15.582,18.081 14.731,18.449C13.879,18.816 12.969,19 12.001,19Z"
android:fillColor="#000000"/>
</vector>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/icon_circle_outline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12.005,19C11.039,19 10.131,18.818 9.281,18.453C8.43,18.089 7.687,17.588 7.049,16.951C6.412,16.313 5.911,15.57 5.547,14.72C5.182,13.871 5,12.961 5,11.992C5,11.023 5.182,10.116 5.547,9.272C5.911,8.427 6.412,7.687 7.049,7.049C7.687,6.412 8.43,5.911 9.28,5.547C10.129,5.182 11.039,5 12.008,5C12.977,5 13.884,5.182 14.728,5.547C15.573,5.911 16.313,6.412 16.951,7.049C17.588,7.687 18.089,8.429 18.453,9.276C18.818,10.122 19,11.029 19,11.995C19,12.961 18.818,13.869 18.453,14.719C18.089,15.57 17.588,16.313 16.951,16.951C16.313,17.588 15.571,18.089 14.724,18.453C13.878,18.818 12.971,19 12.005,19ZM12,17.518C13.536,17.518 14.839,16.983 15.911,15.911C16.983,14.839 17.518,13.536 17.518,12C17.518,10.464 16.983,9.161 15.911,8.089C14.839,7.017 13.536,6.482 12,6.482C10.464,6.482 9.161,7.017 8.089,8.089C7.017,9.161 6.482,10.464 6.482,12C6.482,13.536 7.017,14.839 8.089,15.911C9.161,16.983 10.464,17.518 12,17.518Z"
android:fillColor="#000000"/>
</vector>
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/icon_open_in_new.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M18,19H6c-0.55,0 -1,-0.45 -1,-1V6c0,-0.55 0.45,-1 1,-1h5c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1H5c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2v-6c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v5c0,0.55 -0.45,1 -1,1zM14,4c0,0.55 0.45,1 1,1h2.59l-9.13,9.13c-0.39,0.39 -0.39,1.02 0,1.41 0.39,0.39 1.02,0.39 1.41,0L19,6.41V9c0,0.55 0.45,1 1,1s1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1z"/>

</vector>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/icon_star_filled.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:pathData="m480,667.54 l-155.61,93.84q-8.7,5.08 -17.43,4.27 -8.73,-0.81 -15.8,-5.88 -7.08,-5.08 -10.93,-13.27 -3.84,-8.19 -1.23,-18.12l41.31,-176.69 -137.38,-118.92q-7.7,-6.69 -9.81,-15.5 -2.12,-8.81 1.11,-17.12 3.23,-8.3 9.31,-13.57t16.62,-6.89l181.3,-15.84L451.85,197q3.84,-9.31 11.65,-13.77 7.81,-4.46 16.5,-4.46 8.69,0 16.5,4.46 7.81,4.46 11.65,13.77l70.39,166.85 181.3,15.84q10.54,1.62 16.62,6.89 6.08,5.27 9.31,13.57 3.23,8.31 1.11,17.12 -2.11,8.81 -9.81,15.5L639.69,551.69 681,728.38q2.61,9.93 -1.23,18.12 -3.85,8.19 -10.93,13.27 -7.07,5.07 -15.8,5.88 -8.73,0.81 -17.43,-4.27L480,667.54Z"
android:fillColor="#000"/>
</vector>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/icon_star_outline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:pathData="m354,673 l126,-76 126,77 -33,-144 111,-96 -146,-13 -58,-136 -58,135 -146,13 111,97 -33,143ZM480,667.54 L324.39,761.38q-8.7,5.08 -17.43,4.27 -8.73,-0.81 -15.8,-5.88 -7.08,-5.08 -10.93,-13.27 -3.84,-8.19 -1.23,-18.12l41.31,-176.69 -137.38,-118.92q-7.7,-6.69 -9.81,-15.5 -2.12,-8.81 1.11,-17.12 3.23,-8.3 9.31,-13.57t16.62,-6.89l181.3,-15.84L451.85,197q3.84,-9.31 11.65,-13.77 7.81,-4.46 16.5,-4.46 8.69,0 16.5,4.46 7.81,4.46 11.65,13.77l70.39,166.85 181.3,15.84q10.54,1.62 16.62,6.89 6.08,5.27 9.31,13.57 3.23,8.31 1.11,17.12 -2.11,8.81 -9.81,15.5L639.69,551.69 681,728.38q2.61,9.93 -1.23,18.12 -3.85,8.19 -10.93,13.27 -7.07,5.07 -15.8,5.88 -8.73,0.81 -17.43,-4.27L480,667.54ZM480,490Z"
android:fillColor="#000"/>
</vector>

0 comments on commit b5788ec

Please sign in to comment.