Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): large screen suppport for article list-detail view #846

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ plugins {
alias(libs.plugins.aboutlibraries)
alias(libs.plugins.room)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.parcelize)
}

fun fetchGitCommitHash(): String {
Expand Down Expand Up @@ -131,6 +132,9 @@ dependencies {
implementation(libs.compose.ui.tooling.preview)
androidTestImplementation(libs.compose.ui.test.junit4)
implementation(libs.compose.material3)
implementation(libs.compose.material3.adaptive)
implementation(libs.compose.material3.adaptive.layout)
implementation(libs.compose.material3.adaptive.navigation)

// Accompanist
implementation(libs.accompanist.swiperefresh)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.ash.reader.ui.component.webview

import android.util.Log
import android.view.View
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
Expand Down
29 changes: 26 additions & 3 deletions app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import me.ash.reader.ui.ext.initialFilter
import me.ash.reader.ui.ext.initialPage
import me.ash.reader.ui.ext.isFirstLaunch
import me.ash.reader.ui.page.home.HomeViewModel
import me.ash.reader.ui.page.home.adaptive.ArticleListReaderPage
import me.ash.reader.ui.page.home.feeds.FeedsPage
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewModel
import me.ash.reader.ui.page.home.flow.FlowPage
Expand Down Expand Up @@ -164,13 +165,35 @@ fun HomeEntry(
)
}
animatedComposable(route = RouteName.FLOW) {
FlowPage(

ArticleListReaderPage(
modifier = Modifier,
navController = navController,
homeViewModel = homeViewModel,
homeViewModel = homeViewModel
)
/* FlowPage(
homeViewModel = homeViewModel,
onNavigateToFeeds = {
if (navController.previousBackStackEntry == null) {
navController.navigate(RouteName.FEEDS) {
launchSingleTop = true
}
} else {
navController.popBackStack()
}
}, onOpenArticle = {
navController.navigate("${RouteName.READING}/${it}") {
launchSingleTop = true
}
}
)*/

}
animatedComposable(route = "${RouteName.READING}/{articleId}") {
ReadingPage(navController = navController, homeViewModel = homeViewModel)
ReadingPage(
navController = navController,
homeViewModel = homeViewModel
)
}

// Settings
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package me.ash.reader.ui.page.home.adaptive

import android.os.Parcelable
import androidx.activity.compose.BackHandler
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.material3.adaptive.layout.AnimatedPane
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import kotlinx.parcelize.Parcelize
import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.page.common.RouteName
import me.ash.reader.ui.page.home.HomeViewModel
import me.ash.reader.ui.page.home.flow.FlowPage
import me.ash.reader.ui.page.home.flow.FlowViewModel
import me.ash.reader.ui.page.home.reading.ReadingPage
import me.ash.reader.ui.page.home.reading.ReadingViewModel

@Parcelize
data class ArticleData(val id: String) : Parcelable

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun ArticleListReaderPage(
modifier: Modifier = Modifier,
navController: NavHostController,
flowViewModel: FlowViewModel = hiltViewModel(),
readingViewModel: ReadingViewModel = hiltViewModel(),
homeViewModel: HomeViewModel,
) {
val navigator = rememberListDetailPaneScaffoldNavigator<ArticleData>()
BackHandler(navigator.canNavigateBack()) {
navigator.navigateBack()
}
val readerState = readingViewModel.readerStateStateFlow.collectAsStateValue()

LaunchedEffect(navigator.currentDestination?.content) {
navigator.currentDestination?.content?.id?.let { readingViewModel.initData(it) }
}

ListDetailPaneScaffold(
modifier = modifier,
directive = navigator.scaffoldDirective,
value = navigator.scaffoldValue,
listPane = {
AnimatedPane {
FlowPage(
homeViewModel = homeViewModel,
flowViewModel = flowViewModel,
readingArticleId = readerState.articleId,
onNavigateToFeeds = {
if (navController.previousBackStackEntry == null) {
navController.navigate(RouteName.FEEDS) {
launchSingleTop = true
}
} else {
navController.popBackStack()
}
}, onOpenArticle = {
navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, ArticleData(it))
}
)
}
},
detailPane = {
AnimatedPane {
ReadingPage(
navController = navController,
homeViewModel = homeViewModel,
readingViewModel = readingViewModel
)
}
}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.UnfoldLess
import androidx.compose.material.icons.rounded.UnfoldMore
import androidx.compose.material.rememberModalBottomSheetState

import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
Expand Down Expand Up @@ -131,7 +132,7 @@ fun FeedsPage(
var isSyncing by remember { mutableStateOf(false) }
val syncingState = rememberPullToRefreshState()
val syncingScope = rememberCoroutineScope()
val doSync:() -> Unit = {
val doSync: () -> Unit = {
isSyncing = true
syncingScope.launch {

Expand Down Expand Up @@ -230,13 +231,14 @@ fun FeedsPage(
}
},
content = {

PullToRefreshBox(
state=syncingState,
state = syncingState,
isRefreshing = isSyncing,
onRefresh = doSync
) {
LazyColumn(
modifier=Modifier.fillMaxSize(),
modifier = Modifier.fillMaxSize(),
state = listState
) {
item {
Expand Down Expand Up @@ -351,6 +353,7 @@ fun FeedsPage(
}
}


is GroupFeedsView.Feed -> {
FeedItem(
feed = groupWithFeed.feed,
Expand Down
33 changes: 17 additions & 16 deletions app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package me.ash.reader.ui.page.home.flow

import android.util.Log
import android.view.HapticFeedbackConstants

import androidx.compose.animation.Animatable
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.Spring
Expand All @@ -17,7 +18,6 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -43,32 +43,27 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import coil.size.Precision
import coil.size.Scale
Expand Down Expand Up @@ -104,6 +99,7 @@ private const val TAG = "ArticleItem"
fun ArticleItem(
modifier: Modifier = Modifier,
articleWithFeed: ArticleWithFeed,
isHighlighted: Boolean = false,
onClick: (ArticleWithFeed) -> Unit = {},
onLongClick: (() -> Unit)? = null
) {
Expand All @@ -120,6 +116,7 @@ fun ArticleItem(
imgData = article.img,
isStarred = article.isStarred,
isUnread = article.isUnread,
isHighlighted = isHighlighted,
onClick = { onClick(articleWithFeed) },
onLongClick = onLongClick
)
Expand All @@ -138,6 +135,7 @@ fun ArticleItem(
imgData: Any? = null,
isStarred: Boolean = false,
isUnread: Boolean = false,
isHighlighted: Boolean = false,
onClick: () -> Unit = {},
onLongClick: (() -> Unit)? = null
) {
Expand All @@ -152,19 +150,22 @@ fun ArticleItem(
modifier = modifier
.padding(horizontal = 12.dp)
.clip(Shape20)
.background(if (isHighlighted) MaterialTheme.colorScheme.primaryContainer else Color.Transparent)
.combinedClickable(
onClick = onClick,
onLongClick = onLongClick,
)
.padding(horizontal = 12.dp, vertical = 12.dp)
.alpha(
when (articleListReadIndicator) {
FlowArticleReadIndicatorPreference.AllRead -> {
if (isUnread) 1f else 0.5f
}
if (isHighlighted) 1f else {
when (articleListReadIndicator) {
FlowArticleReadIndicatorPreference.AllRead -> {
if (isUnread) 1f else 0.5f
}

FlowArticleReadIndicatorPreference.ExcludingStarred -> {
if (isUnread || isStarred) 1f else 0.5f
FlowArticleReadIndicatorPreference.ExcludingStarred -> {
if (isUnread || isStarred) 1f else 0.5f
}
}
}
),
Expand Down Expand Up @@ -292,10 +293,9 @@ private const val SwipeActionDelay = 300L
@Composable
fun SwipeableArticleItem(
articleWithFeed: ArticleWithFeed,
isFilterUnread: Boolean = false,
isHighlighted: Boolean = false,
articleListTonalElevation: Int = 0,
onClick: (ArticleWithFeed) -> Unit = {},
isSwipeEnabled: () -> Boolean = { false },
isMenuEnabled: Boolean = true,
onToggleStarred: (ArticleWithFeed) -> Unit = { },
onToggleRead: (ArticleWithFeed) -> Unit = { },
Expand Down Expand Up @@ -349,8 +349,9 @@ fun SwipeableArticleItem(
) {
ArticleItem(
articleWithFeed = articleWithFeed,
isHighlighted = isHighlighted,
onClick = onClick,
onLongClick = onLongClick
onLongClick = onLongClick,
)
with(articleWithFeed.article) {
if (isMenuEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ import me.ash.reader.domain.model.article.ArticleWithFeed
@OptIn(ExperimentalFoundationApi::class)
fun LazyListScope.ArticleList(
pagingItems: LazyPagingItems<ArticleFlowItem>,
isFilterUnread: Boolean,
isShowFeedIcon: Boolean,
isShowStickyHeader: Boolean,
articleListTonalElevation: Int,
isSwipeEnabled: () -> Boolean = { false },
readingArticleId: String?,
isMenuEnabled: Boolean = true,
onClick: (ArticleWithFeed) -> Unit = {},
onToggleStarred: (ArticleWithFeed) -> Unit = { },
Expand All @@ -42,10 +41,9 @@ fun LazyListScope.ArticleList(
is ArticleFlowItem.Article -> {
SwipeableArticleItem(
articleWithFeed = item.articleWithFeed,
isFilterUnread = isFilterUnread,
isHighlighted = readingArticleId == item.articleWithFeed.article.id,
articleListTonalElevation = articleListTonalElevation,
onClick = onClick,
isSwipeEnabled = isSwipeEnabled,
isMenuEnabled = isMenuEnabled,
onToggleStarred = onToggleStarred,
onToggleRead = onToggleRead,
Expand All @@ -72,10 +70,9 @@ fun LazyListScope.ArticleList(
item(key = key(item), contentType = contentType(item)) {
SwipeableArticleItem(
articleWithFeed = item.articleWithFeed,
isFilterUnread = isFilterUnread,
isHighlighted = readingArticleId == item.articleWithFeed.article.id,
articleListTonalElevation = articleListTonalElevation,
onClick = onClick,
isSwipeEnabled = isSwipeEnabled,
isMenuEnabled = isMenuEnabled,
onToggleStarred = onToggleStarred,
onToggleRead = onToggleRead,
Expand Down
Loading
Loading