common: refactor post interactions

This commit is contained in:
Harsh Shandilya 2021-10-15 13:54:46 +05:30
parent 2cfdf30f05
commit 45db8e8486
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
7 changed files with 66 additions and 34 deletions

View file

@ -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),
) )
} }

View file

@ -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),
) )
} }

View file

@ -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),
) )
} }

View file

@ -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,7 +41,8 @@ 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) {
viewModelScope.launch {
val saved = isPostSaved(post) val saved = isPostSaved(post)
println("saved=$saved") println("saved=$saved")
if (saved) { if (saved) {
@ -48,6 +51,7 @@ constructor(
repository.savePost(post) repository.savePost(post)
} }
} }
}
suspend fun getPostComments(postId: String): LobstersPostDetails = suspend fun getPostComments(postId: String): LobstersPostDetails =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {

View file

@ -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) },
) )
} }
} }

View file

@ -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)
}

View file

@ -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),
) )
} }