feat: Compose 举报

This commit is contained in:
HuanCheng65 2024-01-30 14:59:21 +08:00
parent 197d0626a7
commit 0c5c11a88d
No known key found for this signature in database
GPG Key ID: 5EC9DD60A32C7360
7 changed files with 90 additions and 15 deletions

View File

@ -1200,9 +1200,18 @@ interface ITiebaApi {
* @param postId PID
*/
fun checkReportPost(
postId: String
postId: String,
): Call<CheckReportBean>
/**
* 获取举报贴子/回贴页面 URL
*
* @param postId PID
*/
fun checkReportPostAsync(
postId: String,
): Deferred<ApiResult<CheckReportBean>>
/**
* 获得当前用户昵称需登录
*/
@ -1213,7 +1222,7 @@ interface ITiebaApi {
*/
fun initNickNameFlow(
bduss: String,
sToken: String
sToken: String,
): Flow<InitNickNameBean>
/**

View File

@ -910,6 +910,14 @@ object MixedTiebaApiImpl : ITiebaApi {
)
)
override fun checkReportPostAsync(postId: String): Deferred<ApiResult<CheckReportBean>> =
RetrofitTiebaApi.OFFICIAL_TIEBA_API.checkReportAsync(
category = "1",
reportParam = mapOf(
"pid" to postId
)
)
override fun initNickNameFlow(): Flow<InitNickNameBean> =
RetrofitTiebaApi.OFFICIAL_TIEBA_API.initNickNameFlow()

View File

@ -1,15 +1,21 @@
package com.huanchengfly.tieba.post.api.models
import com.google.gson.annotations.SerializedName
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class CheckReportBean(
@SerialName("errno")
@SerializedName("errno")
var errorCode: Int?,
@SerialName("errmsg")
@SerializedName("errmsg")
var errorMsg: String?,
val data: CheckReportDataBean
val data: CheckReportDataBean,
) {
@Serializable
data class CheckReportDataBean(
val url: String?
val url: String = "",
)
}

View File

@ -492,9 +492,19 @@ interface OfficialTiebaApi {
@Field("category") category: String,
@FieldMap reportParam: Map<String, String>,
@Field("stoken") stoken: String? = AccountUtil.getLoginInfo()
?.sToken
?.sToken,
): Call<CheckReportBean>
@Headers("${Header.FORCE_LOGIN}: ${Header.FORCE_LOGIN_TRUE}")
@POST("/c/f/ueg/checkjubao")
@FormUrlEncoded
fun checkReportAsync(
@Field("category") category: String,
@FieldMap reportParam: Map<String, String>,
@Field("stoken") stoken: String? = AccountUtil.getLoginInfo()
?.sToken,
): Deferred<ApiResult<CheckReportBean>>
@Headers("${Header.FORCE_LOGIN}: ${Header.FORCE_LOGIN_TRUE}")
@POST("/c/c/bawu/delthread")
@FormUrlEncoded

View File

@ -24,13 +24,14 @@ import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
import androidx.compose.material.icons.rounded.Close
import androidx.compose.material.icons.rounded.OpenInBrowser
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -88,6 +89,7 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.spec.DestinationStyleBottomSheet
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Destination
@Composable
@ -282,7 +284,7 @@ internal fun SubPostsContent(
navigationIcon = {
IconButton(onClick = { navigator.navigateUp() }) {
Icon(
imageVector = if (isSheet) Icons.Rounded.Close else Icons.Rounded.ArrowBack,
imageVector = if (isSheet) Icons.Rounded.Close else Icons.AutoMirrored.Rounded.ArrowBack,
contentDescription = stringResource(id = R.string.btn_close)
)
}
@ -535,6 +537,8 @@ private fun SubPostItem(
) {
val (subPost, contentRenders, blocked) = item
val context = LocalContext.current
val navigator = LocalNavigator.current
val coroutineScope = rememberCoroutineScope()
val author = remember(subPost) { subPost.get { author }?.wrapImmutable() }
val hasAgreed = remember(subPost) {
subPost.get { agree?.hasAgree == 1 }
@ -576,7 +580,9 @@ private fun SubPostItem(
}
DropdownMenuItem(
onClick = {
TiebaUtil.reportPost(context, subPost.get { id }.toString())
coroutineScope.launch {
TiebaUtil.reportPost(context, navigator, subPost.get { id }.toString())
}
menuState.expanded = false
}
) {

View File

@ -122,6 +122,7 @@ import com.huanchengfly.tieba.post.ui.common.theme.compose.invertChipBackground
import com.huanchengfly.tieba.post.ui.common.theme.compose.invertChipContent
import com.huanchengfly.tieba.post.ui.common.theme.compose.pullRefreshIndicator
import com.huanchengfly.tieba.post.ui.common.theme.compose.threadBottomBar
import com.huanchengfly.tieba.post.ui.page.LocalNavigator
import com.huanchengfly.tieba.post.ui.page.ProvideNavigator
import com.huanchengfly.tieba.post.ui.page.destinations.CopyTextDialogPageDestination
import com.huanchengfly.tieba.post.ui.page.destinations.ForumPageDestination
@ -1167,10 +1168,13 @@ fun ThreadPage(
thread?.get { firstPostId }.takeIf { it != 0L }
?: firstPost?.get { id }
?: 0L
coroutineScope.launch {
TiebaUtil.reportPost(
context,
navigator,
firstPostId.toString()
)
}
},
onDeleteClick = {
deletePost = null
@ -1634,6 +1638,8 @@ fun PostCard(
onMenuDeleteClick: ((Post) -> Unit)? = null,
) {
val context = LocalContext.current
val navigator = LocalNavigator.current
val coroutineScope = rememberCoroutineScope()
val post = remember(postHolder) { postHolder.get() }
val hasPadding = remember(key1 = postHolder, key2 = immersiveMode) {
postHolder.get { floor > 1 } && !immersiveMode
@ -1693,7 +1699,9 @@ fun PostCard(
}
DropdownMenuItem(
onClick = {
TiebaUtil.reportPost(context, post.id.toString())
coroutineScope.launch {
TiebaUtil.reportPost(context, navigator, post.id.toString())
}
menuState.expanded = false
}
) {
@ -1879,6 +1887,8 @@ private fun SubPostItem(
onMenuCopyClick: ((SubPostList) -> Unit)?,
) {
val context = LocalContext.current
val navigator = LocalNavigator.current
val coroutineScope = rememberCoroutineScope()
val menuState = rememberMenuState()
LongClickMenu(
menuState = menuState,
@ -1905,7 +1915,9 @@ private fun SubPostItem(
}
DropdownMenuItem(
onClick = {
TiebaUtil.reportPost(context, subPostList.get { id }.toString())
coroutineScope.launch {
TiebaUtil.reportPost(context, navigator, subPostList.get { id }.toString())
}
menuState.expanded = false
}
) {

View File

@ -14,11 +14,15 @@ import com.huanchengfly.tieba.post.R
import com.huanchengfly.tieba.post.activities.WebViewActivity
import com.huanchengfly.tieba.post.api.TiebaApi
import com.huanchengfly.tieba.post.api.models.CheckReportBean
import com.huanchengfly.tieba.post.api.retrofit.doIfFailure
import com.huanchengfly.tieba.post.api.retrofit.doIfSuccess
import com.huanchengfly.tieba.post.components.dialogs.LoadingDialog
import com.huanchengfly.tieba.post.pendingIntentFlagMutable
import com.huanchengfly.tieba.post.receivers.AutoSignAlarm
import com.huanchengfly.tieba.post.services.OKSignService
import com.huanchengfly.tieba.post.toastShort
import com.huanchengfly.tieba.post.ui.page.destinations.WebViewPageDestination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
@ -125,7 +129,7 @@ object TiebaUtil {
.enqueue(object : Callback<CheckReportBean> {
override fun onResponse(
call: Call<CheckReportBean>,
response: Response<CheckReportBean>
response: Response<CheckReportBean>,
) {
dialog.dismiss()
WebViewActivity.launch(context, response.body()!!.data.url)
@ -137,4 +141,24 @@ object TiebaUtil {
}
})
}
suspend fun reportPost(
context: Context,
navigator: DestinationsNavigator,
postId: String,
) {
val dialog = LoadingDialog(context).apply { show() }
TiebaApi.getInstance()
.checkReportPostAsync(postId)
.doIfSuccess {
dialog.dismiss()
navigator.navigate(
WebViewPageDestination(it.data.url)
)
}
.doIfFailure {
dialog.dismiss()
context.toastShort(R.string.toast_load_failed)
}
}
}