mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 17:37:05 +05:30
common: refactor post interactions
This commit is contained in:
parent
2cfdf30f05
commit
45db8e8486
7 changed files with 66 additions and 34 deletions
|
@ -5,29 +5,25 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.paging.LoadState
|
import androidx.paging.LoadState
|
||||||
import androidx.paging.compose.LazyPagingItems
|
import androidx.paging.compose.LazyPagingItems
|
||||||
import com.google.accompanist.swiperefresh.SwipeRefresh
|
import com.google.accompanist.swiperefresh.SwipeRefresh
|
||||||
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
|
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
|
||||||
|
import dev.msfjarvis.claw.common.posts.PostActions
|
||||||
import dev.msfjarvis.claw.database.local.SavedPost
|
import dev.msfjarvis.claw.database.local.SavedPost
|
||||||
import dev.msfjarvis.claw.model.LobstersPost
|
import dev.msfjarvis.claw.model.LobstersPost
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HottestPosts(
|
fun HottestPosts(
|
||||||
items: LazyPagingItems<LobstersPost>,
|
items: LazyPagingItems<LobstersPost>,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
isPostSaved: suspend (SavedPost) -> Boolean,
|
isPostSaved: suspend (SavedPost) -> Boolean,
|
||||||
toggleSave: suspend (SavedPost) -> Unit,
|
|
||||||
reloadPosts: () -> Unit,
|
reloadPosts: () -> Unit,
|
||||||
launchUrl: (String) -> Unit,
|
postActions: PostActions,
|
||||||
viewComments: (String) -> Unit,
|
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
|
||||||
val isRefreshing = items.loadState.refresh == LoadState.Loading
|
val isRefreshing = items.loadState.refresh == LoadState.Loading
|
||||||
SwipeRefresh(
|
SwipeRefresh(
|
||||||
state = rememberSwipeRefreshState(isRefreshing),
|
state = rememberSwipeRefreshState(isRefreshing),
|
||||||
|
@ -38,11 +34,9 @@ fun HottestPosts(
|
||||||
} else {
|
} else {
|
||||||
NetworkPosts(
|
NetworkPosts(
|
||||||
items = items,
|
items = items,
|
||||||
launchUrl = launchUrl,
|
|
||||||
listState = listState,
|
listState = listState,
|
||||||
isSaved = isPostSaved,
|
isSaved = isPostSaved,
|
||||||
viewComments = viewComments,
|
postActions = postActions,
|
||||||
toggleSave = { coroutineScope.launch { toggleSave(it) } },
|
|
||||||
modifier = Modifier.padding(top = 16.dp).then(modifier),
|
modifier = Modifier.padding(top = 16.dp).then(modifier),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,10 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.mikepenz.markdown.Markdown
|
import com.mikepenz.markdown.Markdown
|
||||||
import dev.msfjarvis.claw.android.viewmodel.ClawViewModel
|
import dev.msfjarvis.claw.android.viewmodel.ClawViewModel
|
||||||
import dev.msfjarvis.claw.common.comments.CommentsPage
|
import dev.msfjarvis.claw.common.comments.CommentsPage
|
||||||
|
import dev.msfjarvis.claw.common.posts.PostActions
|
||||||
import dev.msfjarvis.claw.common.theme.LobstersTheme
|
import dev.msfjarvis.claw.common.theme.LobstersTheme
|
||||||
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
||||||
|
import dev.msfjarvis.claw.database.local.SavedPost
|
||||||
import io.github.furstenheim.CopyDown
|
import io.github.furstenheim.CopyDown
|
||||||
|
|
||||||
private const val ScrollDelta = 50
|
private const val ScrollDelta = 50
|
||||||
|
@ -65,6 +67,21 @@ fun LobstersApp(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val postActions = remember {
|
||||||
|
object : PostActions {
|
||||||
|
override fun viewPost(postUrl: String, commentsUrl: String) {
|
||||||
|
urlLauncher.launch(postUrl.ifEmpty { commentsUrl })
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun viewComments(postId: String) {
|
||||||
|
navController.navigate("comments/$postId")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toggleSave(post: SavedPost) {
|
||||||
|
viewModel.toggleSave(post)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
LobstersTheme(darkTheme = isSystemInDarkTheme()) {
|
LobstersTheme(darkTheme = isSystemInDarkTheme()) {
|
||||||
ProvideWindowInsets {
|
ProvideWindowInsets {
|
||||||
val useDarkIcons = MaterialTheme.colors.isLight
|
val useDarkIcons = MaterialTheme.colors.isLight
|
||||||
|
@ -93,10 +110,8 @@ fun LobstersApp(
|
||||||
items,
|
items,
|
||||||
listState,
|
listState,
|
||||||
viewModel::isPostSaved,
|
viewModel::isPostSaved,
|
||||||
viewModel::toggleSave,
|
|
||||||
viewModel::reloadPosts,
|
viewModel::reloadPosts,
|
||||||
urlLauncher::launch,
|
postActions,
|
||||||
{ navController.navigate("comments/$it") },
|
|
||||||
Modifier.nestedScroll(nestedScrollConnection),
|
Modifier.nestedScroll(nestedScrollConnection),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.paging.compose.LazyPagingItems
|
import androidx.paging.compose.LazyPagingItems
|
||||||
import androidx.paging.compose.items
|
import androidx.paging.compose.items
|
||||||
import dev.msfjarvis.claw.common.posts.LobstersCard
|
import dev.msfjarvis.claw.common.posts.LobstersCard
|
||||||
|
import dev.msfjarvis.claw.common.posts.PostActions
|
||||||
import dev.msfjarvis.claw.common.posts.toDbModel
|
import dev.msfjarvis.claw.common.posts.toDbModel
|
||||||
import dev.msfjarvis.claw.database.local.SavedPost
|
import dev.msfjarvis.claw.database.local.SavedPost
|
||||||
import dev.msfjarvis.claw.model.LobstersPost
|
import dev.msfjarvis.claw.model.LobstersPost
|
||||||
|
@ -23,10 +24,8 @@ import kotlinx.coroutines.launch
|
||||||
fun NetworkPosts(
|
fun NetworkPosts(
|
||||||
items: LazyPagingItems<LobstersPost>,
|
items: LazyPagingItems<LobstersPost>,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
launchUrl: (String) -> Unit,
|
|
||||||
isSaved: suspend (SavedPost) -> Boolean,
|
isSaved: suspend (SavedPost) -> Boolean,
|
||||||
toggleSave: (SavedPost) -> Unit,
|
postActions: PostActions,
|
||||||
viewComments: (String) -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
@ -42,9 +41,7 @@ fun NetworkPosts(
|
||||||
LobstersCard(
|
LobstersCard(
|
||||||
post = dbModel,
|
post = dbModel,
|
||||||
isSaved = saved,
|
isSaved = saved,
|
||||||
viewPost = { launchUrl(item.url.ifEmpty { item.commentsUrl }) },
|
postActions = postActions,
|
||||||
viewComments = { viewComments(item.shortId) },
|
|
||||||
toggleSave = { toggleSave(dbModel) },
|
|
||||||
modifier = Modifier.padding(bottom = 16.dp, start = 16.dp, end = 16.dp),
|
modifier = Modifier.padding(bottom = 16.dp, start = 16.dp, end = 16.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dev.msfjarvis.claw.android.viewmodel
|
package dev.msfjarvis.claw.android.viewmodel
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.paging.Pager
|
import androidx.paging.Pager
|
||||||
import androidx.paging.PagingConfig
|
import androidx.paging.PagingConfig
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
@ -15,6 +16,7 @@ import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.last
|
import kotlinx.coroutines.flow.last
|
||||||
import kotlinx.coroutines.flow.mapLatest
|
import kotlinx.coroutines.flow.mapLatest
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@ -39,13 +41,15 @@ constructor(
|
||||||
return savedPosts.mapLatest { posts -> post in posts }.last()
|
return savedPosts.mapLatest { posts -> post in posts }.last()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun toggleSave(post: SavedPost) {
|
fun toggleSave(post: SavedPost) {
|
||||||
val saved = isPostSaved(post)
|
viewModelScope.launch {
|
||||||
println("saved=$saved")
|
val saved = isPostSaved(post)
|
||||||
if (saved) {
|
println("saved=$saved")
|
||||||
repository.removePost(post)
|
if (saved) {
|
||||||
} else {
|
repository.removePost(post)
|
||||||
repository.savePost(post)
|
} else {
|
||||||
|
repository.savePost(post)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,14 +40,12 @@ import dev.msfjarvis.claw.database.local.SavedPost
|
||||||
fun LobstersCard(
|
fun LobstersCard(
|
||||||
post: SavedPost,
|
post: SavedPost,
|
||||||
isSaved: Boolean,
|
isSaved: Boolean,
|
||||||
viewPost: () -> Unit,
|
postActions: PostActions,
|
||||||
viewComments: (String) -> Unit,
|
|
||||||
toggleSave: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier.background(MaterialTheme.colors.primarySurface).then(modifier),
|
modifier = Modifier.background(MaterialTheme.colors.primarySurface).then(modifier),
|
||||||
onClick = { viewPost() },
|
onClick = { postActions.viewPost(post.url, post.commentsUrl) },
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp).fillMaxWidth(),
|
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp).fillMaxWidth(),
|
||||||
|
@ -63,13 +61,13 @@ fun LobstersCard(
|
||||||
) {
|
) {
|
||||||
SaveButton(
|
SaveButton(
|
||||||
isSaved = isSaved,
|
isSaved = isSaved,
|
||||||
onClick = toggleSave,
|
onClick = { postActions.toggleSave(post) },
|
||||||
)
|
)
|
||||||
Spacer(
|
Spacer(
|
||||||
modifier = Modifier.width(8.dp),
|
modifier = Modifier.width(8.dp),
|
||||||
)
|
)
|
||||||
CommentsButton(
|
CommentsButton(
|
||||||
onClick = { viewComments(post.shortId) },
|
onClick = { postActions.viewComments(post.shortId) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package dev.msfjarvis.claw.common.posts
|
||||||
|
|
||||||
|
import dev.msfjarvis.claw.database.local.SavedPost
|
||||||
|
|
||||||
|
interface PostActions {
|
||||||
|
fun viewPost(postUrl: String, commentsUrl: String)
|
||||||
|
fun viewComments(postId: String)
|
||||||
|
fun toggleSave(post: SavedPost)
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.rememberScrollbarAdapter
|
import androidx.compose.foundation.rememberScrollbarAdapter
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -13,10 +14,13 @@ import androidx.compose.ui.window.WindowPlacement
|
||||||
import androidx.compose.ui.window.WindowPosition
|
import androidx.compose.ui.window.WindowPosition
|
||||||
import androidx.compose.ui.window.application
|
import androidx.compose.ui.window.application
|
||||||
import androidx.compose.ui.window.rememberWindowState
|
import androidx.compose.ui.window.rememberWindowState
|
||||||
|
import dev.msfjarvis.claw.api.LobstersApi
|
||||||
import dev.msfjarvis.claw.common.posts.LobstersCard
|
import dev.msfjarvis.claw.common.posts.LobstersCard
|
||||||
|
import dev.msfjarvis.claw.common.posts.PostActions
|
||||||
import dev.msfjarvis.claw.common.posts.toDbModel
|
import dev.msfjarvis.claw.common.posts.toDbModel
|
||||||
import dev.msfjarvis.claw.common.theme.LobstersTheme
|
import dev.msfjarvis.claw.common.theme.LobstersTheme
|
||||||
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
||||||
|
import dev.msfjarvis.claw.database.local.SavedPost
|
||||||
import org.pushingpixels.aurora.component.AuroraVerticalScrollbar
|
import org.pushingpixels.aurora.component.AuroraVerticalScrollbar
|
||||||
import org.pushingpixels.aurora.skin.ceruleanSkin
|
import org.pushingpixels.aurora.skin.ceruleanSkin
|
||||||
import org.pushingpixels.aurora.window.AuroraWindow
|
import org.pushingpixels.aurora.window.AuroraWindow
|
||||||
|
@ -30,6 +34,19 @@ fun main() = application {
|
||||||
placement = WindowPlacement.Floating,
|
placement = WindowPlacement.Floating,
|
||||||
position = WindowPosition.Aligned(Alignment.Center),
|
position = WindowPosition.Aligned(Alignment.Center),
|
||||||
)
|
)
|
||||||
|
val postActions = remember {
|
||||||
|
object : PostActions {
|
||||||
|
override fun viewPost(postUrl: String, commentsUrl: String) {
|
||||||
|
urlLauncher.launch(postUrl.ifEmpty { commentsUrl })
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun viewComments(postId: String) {
|
||||||
|
urlLauncher.launch("${LobstersApi.BASE_URL}/s/${postId}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toggleSave(post: SavedPost) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
AuroraWindow(
|
AuroraWindow(
|
||||||
skin = ceruleanSkin(),
|
skin = ceruleanSkin(),
|
||||||
title = "Claw",
|
title = "Claw",
|
||||||
|
@ -53,9 +70,7 @@ fun main() = application {
|
||||||
LobstersCard(
|
LobstersCard(
|
||||||
post = item.toDbModel(),
|
post = item.toDbModel(),
|
||||||
isSaved = false,
|
isSaved = false,
|
||||||
viewPost = { urlLauncher.launch(item.url.ifEmpty { item.commentsUrl }) },
|
postActions = postActions,
|
||||||
viewComments = { urlLauncher.launch(item.commentsUrl) },
|
|
||||||
toggleSave = {},
|
|
||||||
modifier = Modifier.padding(bottom = 16.dp, start = 16.dp, end = 16.dp),
|
modifier = Modifier.padding(bottom = 16.dp, start = 16.dp, end = 16.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue