Skip to content

Commit

Permalink
Use swipe library instead of horizontal pager
Browse files Browse the repository at this point in the history
  • Loading branch information
jocmp committed Feb 14, 2025
1 parent f8818be commit 39beb4b
Show file tree
Hide file tree
Showing 25 changed files with 487 additions and 248 deletions.
23 changes: 16 additions & 7 deletions app/src/main/java/com/capyreader/app/ui/articles/ArticleLayout.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ import com.capyreader.app.common.Saver
import com.capyreader.app.refresher.RefreshInterval
import com.capyreader.app.ui.articles.detail.ArticleView
import com.capyreader.app.ui.articles.detail.CapyPlaceholder
import com.capyreader.app.ui.articles.detail.rememberArticlePagination
import com.capyreader.app.ui.articles.list.EmptyOnboardingView
import com.capyreader.app.ui.articles.list.FeedListTopBar
import com.capyreader.app.ui.articles.list.PullToNextFeedBox
import com.capyreader.app.ui.articles.list.resetScrollBehaviorListener
import com.capyreader.app.ui.articles.media.ArticleMediaView
import com.capyreader.app.ui.collectChangesWithDefault
import com.capyreader.app.ui.components.ArticleSearch
import com.capyreader.app.ui.components.rememberWebViewState
import com.jocmp.capy.Article
import com.jocmp.capy.ArticleFilter
import com.jocmp.capy.ArticleStatus
Expand Down Expand Up @@ -437,6 +439,10 @@ fun ArticleLayout(
}
},
detailPane = {
val webViewState = rememberWebViewState(
onNavigateToMedia = { media = it },
)

if (article == null && hasMultipleColumns) {
Box(
contentAlignment = Alignment.Center,
Expand All @@ -445,21 +451,24 @@ fun ArticleLayout(
) {
CapyPlaceholder()
}
} else if (article != null && articles.itemCount > 0) {
} else if (article != null) {
val pagination = rememberArticlePagination(
article,
onSelectArticle = { index, articleID ->
selectArticle(articleID)
scrollToArticle(index)
}
)
ArticleView(
article = article,
onNavigateToMedia = { media = it },
articles = articles,
webViewState = webViewState,
pagination = pagination,
onBackPressed = {
clearArticle()
},
onToggleRead = onToggleArticleRead,
onToggleStar = onToggleArticleStar,
enableBackHandler = media == null,
onRequestArticle = { index, articleID ->
selectArticle(articleID)
scrollToArticle(index)
},
onScrollToArticle = { index ->
scrollToArticle(index)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,7 @@ fun ArticleScreen(
LocalFullContent provides fullContent,
LocalArticleActions provides articleActions,
LocalConnectivity provides connectivity,
LocalArticleLookup provides ArticleLookup(
findIndex = {
viewModel.findArticleIndex(it)
},
),
LocalArticleLookup provides ArticleLookup(viewModel::findArticlePages),
) {
ArticleLayout(
filter = filter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.capyreader.app.ui.components.SearchState
import com.jocmp.capy.Account
import com.jocmp.capy.Article
import com.jocmp.capy.ArticleFilter
import com.jocmp.capy.ArticlePages
import com.jocmp.capy.ArticleStatus
import com.jocmp.capy.Feed
import com.jocmp.capy.Folder
Expand All @@ -30,7 +31,7 @@ import com.jocmp.capy.common.UnauthorizedError
import com.jocmp.capy.common.launchIO
import com.jocmp.capy.common.launchUI
import com.jocmp.capy.countAll
import com.jocmp.capy.findArticleIndex
import com.jocmp.capy.findArticlePages
import com.jocmp.capy.logging.CapyLog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
Expand Down Expand Up @@ -514,6 +515,16 @@ class ArticleScreenViewModel(
}
}

fun findArticlePages(articleID: String): Flow<ArticlePages?> {
return account.findArticlePages(
articleID = articleID,
filter = latestFilter,
query = _searchQuery.value,
unreadSort = unreadSort.value,
since = articlesSince.value
)
}

private suspend fun fetchFullContent(article: Article) {
account.fetchFullContent(article)
.fold(
Expand Down Expand Up @@ -576,16 +587,6 @@ class ArticleScreenViewModel(
}
}

fun findArticleIndex(articleID: String): Int {
return account.findArticleIndex(
articleID = articleID,
filter = latestFilter,
query = _searchQuery.value,
unreadSort = unreadSort.value,
since = articlesSince.value
).toInt()
}

private val latestFilter: ArticleFilter
get() = filter.value

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.capyreader.app.ui.articles

import androidx.compose.runtime.compositionLocalOf
import com.jocmp.capy.ArticlePages
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow

val LocalArticleLookup = compositionLocalOf { ArticleLookup() }

data class ArticleLookup(
val findIndex: (articleID: String) -> Int = { -1 }
val findArticlePages: (articleID: String) -> Flow<ArticlePages?> = { emptyFlow() }
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.capyreader.app.ui.articles.detail

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.capyreader.app.ui.articles.LocalArticleLookup
import com.jocmp.capy.Article
import com.jocmp.capy.ArticlePages

data class ArticlePagination(
val pages: ArticlePages,
val onSelectArticle: (index: Int, id: String) -> Unit,
) {
val hasPrevious = pages.previous > -1
val hasNext = pages.next > -1
val index = pages.current

fun selectPrevious() {
selectArticle(pages.previous, pages.previousID)
}

fun selectNext() {
selectArticle(pages.next, pages.nextID)
}

private fun selectArticle(index: Int, id: String?) {
if (index > -1 && index < pages.size && id != null) {
onSelectArticle(index, id)
}
}
}

@Composable
fun rememberArticlePagination(
article: Article,
onSelectArticle: (index: Int, id: String) -> Unit,
): ArticlePagination {
val lookup = LocalArticleLookup.current
val pages by remember(article.id) {
lookup.findArticlePages(article.id)
}.collectAsStateWithLifecycle(null)

return remember(pages, onSelectArticle) {
val pagesWithDefault = pages ?: ArticlePages(current = -2, size = 0)

ArticlePagination(
pagesWithDefault,
onSelectArticle,
)
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.capyreader.app.ui.articles.detail

import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
Expand All @@ -20,20 +20,19 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.unit.dp
import com.capyreader.app.common.AppPreferences
import com.capyreader.app.common.Media
import com.capyreader.app.common.ReaderImageVisibility
import com.capyreader.app.ui.ConnectivityType
import com.capyreader.app.ui.LocalConnectivity
import com.capyreader.app.ui.articles.ColumnScrollbar
import com.capyreader.app.ui.components.WebView
import com.capyreader.app.ui.components.rememberWebViewState
import com.capyreader.app.ui.components.WebViewState
import com.jocmp.capy.Article
import org.koin.compose.koinInject

@Composable
fun ArticleReader(
article: Article,
onNavigateToMedia: (media: Media) -> Unit,
webViewState: WebViewState,
) {
val showImages = rememberImageVisibility()
var maxHeight by remember { mutableFloatStateOf(0f) }
Expand All @@ -43,11 +42,7 @@ fun ArticleReader(

var lastScrollY by rememberSaveable { mutableIntStateOf(0) }

val webViewState = rememberWebViewState(
onNavigateToMedia = onNavigateToMedia,
)

ReaderPagingBox(
CornerTapGestureScroll(
maxArticleHeight = maxHeight,
scrollState = scrollState,
) {
Expand Down Expand Up @@ -83,6 +78,12 @@ fun ArticleReader(
}

ArticleStyleListener(webView = webViewState.webView)

DisposableEffect(article.id) {
onDispose {
webViewState.reset()
}
}
}

@Composable
Expand Down
Loading

0 comments on commit 39beb4b

Please sign in to comment.