Skip to content

Commit

Permalink
Post removing (#1324)
Browse files Browse the repository at this point in the history
* Adding ability to remove and restore comments. #1182

* Fix weird formatting miss.

* Use ImmutableList instead of List.

* Surrounding canMod with remember.

* Adding ability to remove and restore posts. #1182

* Fixing jerboaappstate.

* Removing extra RemoveViewModel.

* Changing remove icon to gavel.

* Change a few strings to non-contextual.

* Add remove comment to commentmentionnode.

* Remove non-optional body from compiler warning.

* Wrapping remember around moderators.
  • Loading branch information
dessalines committed Jan 21, 2024
1 parent 47ee753 commit 4a9ffba
Show file tree
Hide file tree
Showing 20 changed files with 381 additions and 16 deletions.
7 changes: 7 additions & 0 deletions app/src/main/java/com/jerboa/JerboaAppState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ import com.jerboa.ui.components.post.create.CreatePostReturn
import com.jerboa.ui.components.post.edit.PostEditReturn
import com.jerboa.ui.components.privatemessage.PrivateMessage
import com.jerboa.ui.components.remove.comment.CommentRemoveReturn
import com.jerboa.ui.components.remove.post.PostRemoveReturn
import it.vercruysse.lemmyapi.v0x19.datatypes.Comment
import it.vercruysse.lemmyapi.v0x19.datatypes.CommentView
import it.vercruysse.lemmyapi.v0x19.datatypes.Community
import it.vercruysse.lemmyapi.v0x19.datatypes.CommunityView
import it.vercruysse.lemmyapi.v0x19.datatypes.Post
import it.vercruysse.lemmyapi.v0x19.datatypes.PostView
import it.vercruysse.lemmyapi.v0x19.datatypes.PrivateMessageView
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -70,6 +72,11 @@ class JerboaAppState(
navController.navigate(Route.PostReportArgs.makeRoute(id = "$id"))
}

fun toPostRemove(post: Post) {
sendReturnForwards(PostRemoveReturn.POST_SEND, post)
navController.navigate(Route.POST_REMOVE)
}

fun toCommentRemove(comment: Comment) {
sendReturnForwards(CommentRemoveReturn.COMMENT_SEND, comment)
navController.navigate(Route.COMMENT_REMOVE)
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/com/jerboa/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import com.jerboa.ui.components.post.edit.PostEditActivity
import com.jerboa.ui.components.privatemessage.CreatePrivateMessageActivity
import com.jerboa.ui.components.privatemessage.PrivateMessageReplyActivity
import com.jerboa.ui.components.remove.comment.CommentRemoveActivity
import com.jerboa.ui.components.remove.post.PostRemoveActivity
import com.jerboa.ui.components.report.comment.CreateCommentReportActivity
import com.jerboa.ui.components.report.post.CreatePostReportActivity
import com.jerboa.ui.components.settings.SettingsActivity
Expand Down Expand Up @@ -557,6 +558,15 @@ class MainActivity : AppCompatActivity() {
)
}

composable(
route = Route.POST_REMOVE,
) {
PostRemoveActivity(
appState = appState,
accountViewModel = accountViewModel,
)
}

composable(
route = Route.COMMENT_REMOVE,
) {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/jerboa/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1455,7 +1455,7 @@ fun Context.getInputStream(url: String): InputStream {
Request.Builder()
.url(url)
.build(),
).execute().body?.byteStream() ?: throw IOException("Failed to get input stream")
).execute().body.byteStream()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@ import com.jerboa.api.API
import com.jerboa.api.ApiState
import com.jerboa.api.toApiState
import com.jerboa.ui.components.common.apiErrorToast
import it.vercruysse.lemmyapi.v0x19.datatypes.CommentId
import it.vercruysse.lemmyapi.v0x19.datatypes.CommentResponse
import it.vercruysse.lemmyapi.v0x19.datatypes.CommentView
import it.vercruysse.lemmyapi.v0x19.datatypes.RemoveComment
import kotlinx.coroutines.launch

class RemoveViewModel : ViewModel() {
class CommentRemoveViewModel : ViewModel() {
var commentRemoveRes: ApiState<CommentResponse> by mutableStateOf(ApiState.Empty)
private set

fun removeOrRestoreComment(
commentId: Int,
commentId: CommentId,
removed: Boolean,
reason: String,
ctx: Context,
Expand All @@ -51,9 +52,9 @@ class RemoveViewModel : ViewModel() {
is ApiState.Success -> {
val message =
if (removed) {
ctx.getString(R.string.remove_view_model_comment_removed)
ctx.getString(R.string.comment_removed)
} else {
ctx.getString(R.string.remove_view_model_comment_restored)
ctx.getString(R.string.comment_restored)
}
val commentView = res.data.comment_view
Toast.makeText(ctx, message, Toast.LENGTH_SHORT).show()
Expand Down
69 changes: 69 additions & 0 deletions app/src/main/java/com/jerboa/model/PostRemoveViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.jerboa.model

import android.content.Context
import android.util.Log
import android.widget.Toast
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.focus.FocusManager
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.jerboa.R
import com.jerboa.api.API
import com.jerboa.api.ApiState
import com.jerboa.api.toApiState
import com.jerboa.ui.components.common.apiErrorToast
import it.vercruysse.lemmyapi.v0x19.datatypes.PostId
import it.vercruysse.lemmyapi.v0x19.datatypes.PostResponse
import it.vercruysse.lemmyapi.v0x19.datatypes.PostView
import it.vercruysse.lemmyapi.v0x19.datatypes.RemovePost
import kotlinx.coroutines.launch

class PostRemoveViewModel : ViewModel() {
var postRemoveRes: ApiState<PostResponse> by mutableStateOf(ApiState.Empty)
private set

fun removeOrRestorePost(
postId: PostId,
removed: Boolean,
reason: String,
ctx: Context,
focusManager: FocusManager,
onSuccess: (PostView) -> Unit,
) {
viewModelScope.launch {
val form =
RemovePost(
post_id = postId,
removed = removed,
reason = reason,
)

postRemoveRes = ApiState.Loading
postRemoveRes = API.getInstance().removePost(form).toApiState()

when (val res = postRemoveRes) {
is ApiState.Failure -> {
Log.d("removePost", "failed", res.msg)
apiErrorToast(msg = res.msg, ctx = ctx)
}

is ApiState.Success -> {
val message =
if (removed) {
ctx.getString(R.string.post_removed)
} else {
ctx.getString(R.string.post_restored)
}
val postView = res.data.post_view
Toast.makeText(ctx, message, Toast.LENGTH_SHORT).show()

focusManager.clearFocus()
onSuccess(postView)
}
else -> {}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ package com.jerboa.ui.components.comment
import android.widget.Toast
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Block
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.Comment
import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material.icons.outlined.CopyAll
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Description
import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material.icons.outlined.Flag
import androidx.compose.material.icons.outlined.Gavel
import androidx.compose.material.icons.outlined.Link
import androidx.compose.material.icons.outlined.Person
import androidx.compose.material.icons.outlined.Restore
Expand Down Expand Up @@ -178,7 +178,7 @@ fun CommentOptionsDropdown(
if (commentView.comment.removed) {
Pair(stringResource(R.string.restore_comment), Icons.Outlined.Restore)
} else {
Pair(stringResource(R.string.remove_comment), Icons.Outlined.Close)
Pair(stringResource(R.string.remove_comment), Icons.Outlined.Gavel)
}

PopupMenuItem(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.jerboa.R
import com.jerboa.VoteType
import com.jerboa.canMod
import com.jerboa.datatypes.samplePersonMentionView
import com.jerboa.db.entity.Account
import com.jerboa.ui.components.comment.CommentBody
Expand All @@ -40,8 +41,11 @@ import com.jerboa.ui.theme.SMALL_PADDING
import com.jerboa.ui.theme.XXL_PADDING
import com.jerboa.ui.theme.muted
import it.vercruysse.lemmyapi.v0x19.datatypes.Community
import it.vercruysse.lemmyapi.v0x19.datatypes.CommunityModeratorView
import it.vercruysse.lemmyapi.v0x19.datatypes.Person
import it.vercruysse.lemmyapi.v0x19.datatypes.PersonMentionView
import it.vercruysse.lemmyapi.v0x19.datatypes.PersonView
import kotlinx.collections.immutable.ImmutableList

@Composable
fun CommentMentionNodeHeader(
Expand Down Expand Up @@ -91,6 +95,8 @@ fun CommentMentionNodeHeaderPreview() {
@Composable
fun CommentMentionNodeFooterLine(
personMentionView: PersonMentionView,
admins: ImmutableList<PersonView>,
moderators: ImmutableList<CommunityModeratorView>?,
onUpvoteClick: () -> Unit,
onDownvoteClick: () -> Unit,
onReplyClick: (personMentionView: PersonMentionView) -> Unit,
Expand All @@ -112,6 +118,16 @@ fun CommentMentionNodeFooterLine(
) {
var showMoreOptions by remember { mutableStateOf(false) }

val canMod =
remember {
canMod(
creatorId = personMentionView.comment.creator_id,
admins = admins,
moderators = moderators,
myId = account.id,
)
}

if (showMoreOptions) {
CommentMentionsOptionsDropdown(
personMentionView = personMentionView,
Expand All @@ -123,6 +139,7 @@ fun CommentMentionNodeFooterLine(
onBlockCreatorClick = onBlockCreatorClick,
isCreator = account.id == personMentionView.creator.id,
onCommentLinkClick = onLinkClick,
canMod = canMod,
viewSource = viewSource,
)
}
Expand Down Expand Up @@ -228,6 +245,8 @@ fun CommentMentionNodeFooterLine(
@Composable
fun CommentMentionNode(
personMentionView: PersonMentionView,
admins: ImmutableList<PersonView>,
moderators: ImmutableList<CommunityModeratorView>?,
onUpvoteClick: (personMentionView: PersonMentionView) -> Unit,
onDownvoteClick: (personMentionView: PersonMentionView) -> Unit,
onReplyClick: (personMentionView: PersonMentionView) -> Unit,
Expand Down Expand Up @@ -303,6 +322,8 @@ fun CommentMentionNode(
) {
CommentMentionNodeFooterLine(
personMentionView = personMentionView,
admins = admins,
moderators = moderators,
onUpvoteClick = {
onUpvoteClick(personMentionView)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material.icons.outlined.CopyAll
import androidx.compose.material.icons.outlined.Description
import androidx.compose.material.icons.outlined.Flag
import androidx.compose.material.icons.outlined.Gavel
import androidx.compose.material.icons.outlined.Link
import androidx.compose.material.icons.outlined.Person
import androidx.compose.material.icons.outlined.Restore
import androidx.compose.material3.Divider
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalClipboardManager
Expand All @@ -35,6 +37,7 @@ fun CommentMentionsOptionsDropdown(
onReportClick: (PersonMentionView) -> Unit,
onRemoveClick: (PersonMentionView) -> Unit,
isCreator: Boolean,
canMod: Boolean,
viewSource: Boolean,
) {
val localClipboardManager = LocalClipboardManager.current
Expand Down Expand Up @@ -128,5 +131,24 @@ fun CommentMentionsOptionsDropdown(
},
)
}

if (canMod) {
Divider()
val (removeText, removeIcon) =
if (personMentionView.comment.removed) {
Pair(stringResource(R.string.restore_comment), Icons.Outlined.Restore)
} else {
Pair(stringResource(R.string.remove_comment), Icons.Outlined.Gavel)
}

PopupMenuItem(
text = removeText,
icon = removeIcon,
onClick = {
onDismissRequest()
onRemoveClick(personMentionView)
},
)
}
}
}
1 change: 1 addition & 0 deletions app/src/main/java/com/jerboa/ui/components/common/Route.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ object Route {
const val SITE_SIDEBAR = "siteSidebar"
const val COMMENT_EDIT = "commentEdit"
const val POST_EDIT = "postEdit"
const val POST_REMOVE = "postRemove"
const val PRIVATE_MESSAGE_REPLY = "privateMessageReply"
const val COMMENT_REMOVE = "commentRemove"
val CREATE_PRIVATE_MESSAGE = CreatePrivateMessageArgs.route
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import com.jerboa.ui.components.common.isRefreshing
import com.jerboa.ui.components.post.PostListings
import com.jerboa.ui.components.post.PostViewReturn
import com.jerboa.ui.components.post.edit.PostEditReturn
import com.jerboa.ui.components.remove.post.PostRemoveReturn
import it.vercruysse.lemmyapi.dto.SubscribedType
import it.vercruysse.lemmyapi.v0x19.datatypes.BlockCommunity
import it.vercruysse.lemmyapi.v0x19.datatypes.CommunityId
Expand Down Expand Up @@ -96,6 +97,7 @@ fun CommunityActivity(
viewModel(factory = CommunityViewModel.Companion.Factory(communityArg))

appState.ConsumeReturn<PostView>(PostEditReturn.POST_VIEW, communityViewModel::updatePost)
appState.ConsumeReturn<PostView>(PostRemoveReturn.POST_VIEW, communityViewModel::updatePost)
appState.ConsumeReturn<PostView>(PostViewReturn.POST_VIEW, communityViewModel::updatePost)

val pullRefreshState =
Expand Down Expand Up @@ -190,10 +192,23 @@ fun CommunityActivity(
ApiState.Empty -> ApiEmptyText()
is ApiState.Failure -> ApiErrorText(postsRes.msg)
is ApiState.Holder -> {
val communityRes = communityViewModel.communityRes
val moderators =
remember(communityRes) {
when (communityRes) {
is ApiState.Success -> communityRes.data.moderators.toImmutableList()
else -> {
null
}
}
}

PostListings(
posts = postsRes.data.posts.toImmutableList(),
admins = siteViewModel.admins(),
moderators = moderators,
contentAboveListings = {
when (val communityRes = communityViewModel.communityRes) {
when (communityRes) {
is ApiState.Success -> {
CommunityTopSection(
communityView = communityRes.data.community_view,
Expand Down Expand Up @@ -315,6 +330,9 @@ fun CommunityActivity(
onReportClick = { postView ->
appState.toPostReport(id = postView.post.id)
},
onRemoveClick = { pv ->
appState.toPostRemove(post = pv.post)
},
onCommunityClick = { community ->
appState.toCommunity(id = community.id)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import com.jerboa.ui.components.common.isRefreshing
import com.jerboa.ui.components.post.PostListings
import com.jerboa.ui.components.post.PostViewReturn
import com.jerboa.ui.components.post.edit.PostEditReturn
import com.jerboa.ui.components.remove.post.PostRemoveReturn
import it.vercruysse.lemmyapi.v0x19.datatypes.CreatePostLike
import it.vercruysse.lemmyapi.v0x19.datatypes.DeletePost
import it.vercruysse.lemmyapi.v0x19.datatypes.MarkPostAsRead
Expand Down Expand Up @@ -104,6 +105,7 @@ fun HomeActivity(
val snackbarHostState = remember(account) { SnackbarHostState() }

appState.ConsumeReturn<PostView>(PostEditReturn.POST_VIEW, homeViewModel::updatePost)
appState.ConsumeReturn<PostView>(PostRemoveReturn.POST_VIEW, homeViewModel::updatePost)
appState.ConsumeReturn<PostView>(PostViewReturn.POST_VIEW, homeViewModel::updatePost)

LaunchedEffect(account) {
Expand Down Expand Up @@ -251,6 +253,9 @@ fun MainPostListingsContent(

PostListings(
posts = posts,
admins = siteViewModel.admins(),
// No community moderators available here
moderators = null,
contentAboveListings = { if (taglines !== null) Taglines(taglines = taglines.toImmutableList()) },
onUpvoteClick = { postView ->
account.doIfReadyElseDisplayInfo(
Expand Down Expand Up @@ -335,6 +340,9 @@ fun MainPostListingsContent(
onReportClick = { postView ->
appState.toPostReport(id = postView.post.id)
},
onRemoveClick = { pv ->
appState.toPostRemove(post = pv.post)
},
onCommunityClick = { community ->
appState.toCommunity(id = community.id)
},
Expand Down
Loading

0 comments on commit 4a9ffba

Please sign in to comment.