diff --git a/.kotlin/sessions/kotlin-compiler-7540113872150378976.salive b/.kotlin/sessions/kotlin-compiler-7540113872150378976.salive new file mode 100644 index 00000000..e69de29b diff --git a/app/src/main/java/com/capyreader/app/ui/articles/ArticleActions.kt b/app/src/main/java/com/capyreader/app/ui/articles/ArticleActions.kt index 04a41b4f..9aa594dd 100644 --- a/app/src/main/java/com/capyreader/app/ui/articles/ArticleActions.kt +++ b/app/src/main/java/com/capyreader/app/ui/articles/ArticleActions.kt @@ -1,7 +1,14 @@ package com.capyreader.app.ui.articles +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.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.compositionLocalOf +import com.jocmp.capy.Article val LocalArticleActions = compositionLocalOf { ArticleActions() } diff --git a/app/src/main/java/com/capyreader/app/ui/articles/ArticleRow.kt b/app/src/main/java/com/capyreader/app/ui/articles/ArticleRow.kt index 5a0db57d..92583650 100644 --- a/app/src/main/java/com/capyreader/app/ui/articles/ArticleRow.kt +++ b/app/src/main/java/com/capyreader/app/ui/articles/ArticleRow.kt @@ -186,7 +186,7 @@ fun ArticleRow( ArticleActionMenu( expanded = isArticleMenuOpen, - articleID = article.id, + article = article, onMarkAllRead = { setArticleMenuOpen(false) onMarkAllRead(it) diff --git a/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleActionMenu.kt b/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleActionMenu.kt index 9f9a21ef..daa0d5dd 100644 --- a/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleActionMenu.kt +++ b/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleActionMenu.kt @@ -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 = {}, ) { @@ -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( @@ -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 = { @@ -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 ) } diff --git a/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleRowSwipeBox.kt b/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleRowSwipeBox.kt index 408e6b03..55ed1538 100644 --- a/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleRowSwipeBox.kt +++ b/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleRowSwipeBox.kt @@ -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 @@ -50,7 +51,7 @@ fun ArticleRowSwipeBox( .background(color) ) { Icon( - action.icon, + painterResource(action.icon), contentDescription = stringResource(id = action.translationKey), modifier = Modifier .padding(24.dp) diff --git a/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleRowSwipeState.kt b/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleRowSwipeState.kt index 40bd620f..0ad95e34 100644 --- a/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleRowSwipeState.kt +++ b/app/src/main/java/com/capyreader/app/ui/articles/list/ArticleRowSwipeState.kt @@ -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 @@ -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) - } - } -} diff --git a/app/src/main/java/com/capyreader/app/ui/components/ArticleAction.kt b/app/src/main/java/com/capyreader/app/ui/components/ArticleAction.kt new file mode 100644 index 00000000..b51853cb --- /dev/null +++ b/app/src/main/java/com/capyreader/app/ui/components/ArticleAction.kt @@ -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) + } + } diff --git a/app/src/main/res/drawable/icon_circle_filled.xml b/app/src/main/res/drawable/icon_circle_filled.xml index 92d73bf8..f7d06632 100644 --- a/app/src/main/res/drawable/icon_circle_filled.xml +++ b/app/src/main/res/drawable/icon_circle_filled.xml @@ -1,9 +1,9 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + 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"/> diff --git a/app/src/main/res/drawable/icon_circle_outline.xml b/app/src/main/res/drawable/icon_circle_outline.xml new file mode 100644 index 00000000..ca272845 --- /dev/null +++ b/app/src/main/res/drawable/icon_circle_outline.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/icon_open_in_new.xml b/app/src/main/res/drawable/icon_open_in_new.xml new file mode 100644 index 00000000..7bdb080a --- /dev/null +++ b/app/src/main/res/drawable/icon_open_in_new.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/icon_star_filled.xml b/app/src/main/res/drawable/icon_star_filled.xml new file mode 100644 index 00000000..bedd26db --- /dev/null +++ b/app/src/main/res/drawable/icon_star_filled.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/icon_star_outline.xml b/app/src/main/res/drawable/icon_star_outline.xml new file mode 100644 index 00000000..b3fff6d8 --- /dev/null +++ b/app/src/main/res/drawable/icon_star_outline.xml @@ -0,0 +1,9 @@ + + +