mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 12:18:45 +01:00
fix: instance unban (#887)
This commit is contained in:
parent
30379ef681
commit
af239aafb4
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class BlockSiteForm(
|
||||
data class BlockInstanceForm(
|
||||
@SerialName("instance_id") val instanceId: InstanceId,
|
||||
@SerialName("block") val block: Boolean,
|
||||
)
|
@ -0,0 +1,9 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.api.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class BlockInstanceResponse(
|
||||
@SerialName("blocked") val blocked: Boolean,
|
||||
)
|
@ -1,6 +1,7 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.api.service
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.BlockSiteForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.BlockInstanceForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.BlockInstanceResponse
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.GetSiteResponse
|
||||
import de.jensklingenberg.ktorfit.Response
|
||||
import de.jensklingenberg.ktorfit.http.Body
|
||||
@ -21,6 +22,6 @@ interface SiteService {
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun block(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: BlockSiteForm,
|
||||
): Response<GetSiteResponse>
|
||||
@Body form: BlockInstanceForm,
|
||||
): Response<BlockInstanceResponse>
|
||||
}
|
||||
|
@ -423,24 +423,24 @@ class DefaultCommunityRepositoryTest {
|
||||
mockk {
|
||||
every { isSuccessful } returns true
|
||||
every { body() } returns mockk()
|
||||
|
||||
val token = "fake-token"
|
||||
sut.block(
|
||||
auth = token,
|
||||
id = communityId,
|
||||
blocked = true,
|
||||
)
|
||||
|
||||
coVerify {
|
||||
communityService.block(
|
||||
authHeader = token.toAuthHeader(),
|
||||
withArg { data ->
|
||||
assertEquals(communityId, data.communityId)
|
||||
assertTrue(data.block)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
val token = "fake-token"
|
||||
|
||||
sut.block(
|
||||
auth = token,
|
||||
id = communityId,
|
||||
blocked = true,
|
||||
)
|
||||
|
||||
coVerify {
|
||||
communityService.block(
|
||||
authHeader = token.toAuthHeader(),
|
||||
withArg { data ->
|
||||
assertEquals(communityId, data.communityId)
|
||||
assertTrue(data.block)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -64,7 +64,7 @@ interface CommunityRepository {
|
||||
id: Long,
|
||||
blocked: Boolean,
|
||||
auth: String?,
|
||||
): Result<Unit>
|
||||
)
|
||||
|
||||
suspend fun banUser(
|
||||
auth: String?,
|
||||
|
@ -217,21 +217,18 @@ internal class DefaultCommunityRepository(
|
||||
id: Long,
|
||||
blocked: Boolean,
|
||||
auth: String?,
|
||||
): Result<Unit> =
|
||||
): Unit =
|
||||
withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val data =
|
||||
BlockCommunityForm(
|
||||
communityId = id,
|
||||
block = blocked,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
services.community.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
val data =
|
||||
BlockCommunityForm(
|
||||
communityId = id,
|
||||
block = blocked,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
Unit
|
||||
}
|
||||
services.community.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun banUser(
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.BlockSiteForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.BlockInstanceForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.provider.ServiceProvider
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.AccountBansModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.AccountSettingsModel
|
||||
@ -61,20 +61,18 @@ internal class DefaultSiteRepository(
|
||||
id: Long,
|
||||
blocked: Boolean,
|
||||
auth: String?,
|
||||
): Result<Unit> =
|
||||
): Unit =
|
||||
withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val data =
|
||||
BlockSiteForm(
|
||||
instanceId = id,
|
||||
block = blocked,
|
||||
)
|
||||
services.site.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
val data =
|
||||
BlockInstanceForm(
|
||||
instanceId = id,
|
||||
block = blocked,
|
||||
)
|
||||
Unit
|
||||
}
|
||||
services.site.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
Unit
|
||||
}
|
||||
|
||||
override suspend fun getMetadata(url: String): MetadataModel? =
|
||||
|
@ -285,21 +285,19 @@ internal class DefaultUserRepository(
|
||||
id: Long,
|
||||
blocked: Boolean,
|
||||
auth: String?,
|
||||
): Result<Unit> =
|
||||
): Unit =
|
||||
withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val data =
|
||||
BlockPersonForm(
|
||||
personId = id,
|
||||
block = blocked,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
services.user.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
val data =
|
||||
BlockPersonForm(
|
||||
personId = id,
|
||||
block = blocked,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
Unit
|
||||
}
|
||||
services.user.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
Unit
|
||||
}
|
||||
|
||||
override suspend fun getModeratedCommunities(
|
||||
|
@ -18,7 +18,7 @@ interface SiteRepository {
|
||||
id: Long,
|
||||
blocked: Boolean,
|
||||
auth: String? = null,
|
||||
): Result<Unit>
|
||||
)
|
||||
|
||||
suspend fun getMetadata(url: String): MetadataModel?
|
||||
|
||||
|
@ -90,7 +90,7 @@ interface UserRepository {
|
||||
id: Long,
|
||||
blocked: Boolean,
|
||||
auth: String? = null,
|
||||
): Result<Unit>
|
||||
)
|
||||
|
||||
suspend fun getModeratedCommunities(
|
||||
auth: String? = null,
|
||||
|
@ -394,7 +394,7 @@ class CommunityDetailScreen(
|
||||
this +=
|
||||
Option(
|
||||
OptionId.Block,
|
||||
LocalXmlStrings.current.communityDetailBlock,
|
||||
LocalXmlStrings.current.blockActionCommunity,
|
||||
)
|
||||
this +=
|
||||
Option(
|
||||
|
@ -595,7 +595,11 @@ class CommunityDetailViewModel(
|
||||
updateState { it.copy(asyncInProgress = true) }
|
||||
try {
|
||||
val auth = identityRepository.authToken.value
|
||||
communityRepository.block(communityId, true, auth).getOrThrow()
|
||||
communityRepository.block(
|
||||
id = communityId,
|
||||
blocked = true,
|
||||
auth = auth,
|
||||
)
|
||||
emitEffect(CommunityDetailMviModel.Effect.Success)
|
||||
} catch (e: Throwable) {
|
||||
emitEffect(CommunityDetailMviModel.Effect.Error(e.message))
|
||||
@ -612,7 +616,7 @@ class CommunityDetailViewModel(
|
||||
val community = uiState.value.community
|
||||
val instanceId = community.instanceId
|
||||
val auth = identityRepository.authToken.value
|
||||
siteRepository.block(instanceId, true, auth).getOrThrow()
|
||||
siteRepository.block(instanceId, true, auth)
|
||||
emitEffect(CommunityDetailMviModel.Effect.Success)
|
||||
} catch (e: Throwable) {
|
||||
emitEffect(CommunityDetailMviModel.Effect.Error(e.message))
|
||||
|
@ -40,5 +40,9 @@ interface ManageBanMviModel :
|
||||
val bannedInstances: List<InstanceModel> = emptyList(),
|
||||
)
|
||||
|
||||
sealed interface Effect
|
||||
sealed interface Effect {
|
||||
data object Success : Effect
|
||||
|
||||
data class Failure(val message: String?) : Effect
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
||||
import androidx.compose.material.pullrefresh.pullRefresh
|
||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
@ -27,9 +28,11 @@ import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
@ -50,6 +53,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallbackArgs
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.manageban.components.InstanceItem
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
class ManageBanScreen : Screen {
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
|
||||
@ -64,6 +69,22 @@ class ManageBanScreen : Screen {
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
val lazyListState = rememberLazyListState()
|
||||
val successMessage = LocalXmlStrings.current.messageOperationSuccessful
|
||||
val errorMessage = LocalXmlStrings.current.messageGenericError
|
||||
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach { evt ->
|
||||
when (evt) {
|
||||
is ManageBanMviModel.Effect.Failure -> {
|
||||
snackbarHostState.showSnackbar(evt.message ?: errorMessage)
|
||||
}
|
||||
|
||||
ManageBanMviModel.Effect.Success -> {
|
||||
snackbarHostState.showSnackbar(successMessage)
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.background),
|
||||
@ -200,13 +221,11 @@ class ManageBanScreen : Screen {
|
||||
)
|
||||
},
|
||||
onOptionSelected =
|
||||
rememberCallbackArgs(model) { optionId ->
|
||||
rememberCallbackArgs(user) { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Unban -> {
|
||||
model.reduce(
|
||||
ManageBanMviModel.Intent.UnblockUser(
|
||||
user.id,
|
||||
),
|
||||
ManageBanMviModel.Intent.UnblockUser(user.id),
|
||||
)
|
||||
}
|
||||
|
||||
@ -250,13 +269,11 @@ class ManageBanScreen : Screen {
|
||||
)
|
||||
},
|
||||
onOptionSelected =
|
||||
rememberCallbackArgs(model) { optionId ->
|
||||
rememberCallbackArgs(community) { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Unban -> {
|
||||
model.reduce(
|
||||
ManageBanMviModel.Intent.UnblockCommunity(
|
||||
community.id,
|
||||
),
|
||||
ManageBanMviModel.Intent.UnblockCommunity(community.id),
|
||||
)
|
||||
}
|
||||
|
||||
@ -298,13 +315,11 @@ class ManageBanScreen : Screen {
|
||||
)
|
||||
},
|
||||
onOptionSelected =
|
||||
rememberCallbackArgs(model) { optionId ->
|
||||
rememberCallbackArgs(instance) { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Unban -> {
|
||||
model.reduce(
|
||||
ManageBanMviModel.Intent.UnblockInstance(
|
||||
instance.id,
|
||||
),
|
||||
ManageBanMviModel.Intent.UnblockInstance(instance.id),
|
||||
)
|
||||
}
|
||||
|
||||
@ -317,6 +332,14 @@ class ManageBanScreen : Screen {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PullRefreshIndicator(
|
||||
refreshing = uiState.refreshing,
|
||||
state = pullRefreshState,
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
backgroundColor = MaterialTheme.colorScheme.background,
|
||||
contentColor = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ class ManageBanViewModel(
|
||||
private fun unbanUser(id: Long) {
|
||||
screenModelScope.launch {
|
||||
val auth = identityRepository.authToken.value.orEmpty()
|
||||
runCatching {
|
||||
try {
|
||||
userRepository.block(
|
||||
id = id,
|
||||
blocked = false,
|
||||
@ -83,6 +83,9 @@ class ManageBanViewModel(
|
||||
updateState {
|
||||
it.copy(bannedUsers = it.bannedUsers.filter { e -> e.id != id })
|
||||
}
|
||||
emitEffect(ManageBanMviModel.Effect.Success)
|
||||
} catch (e: Throwable) {
|
||||
emitEffect(ManageBanMviModel.Effect.Failure(e.message))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,7 +93,7 @@ class ManageBanViewModel(
|
||||
private fun unbanCommunity(id: Long) {
|
||||
screenModelScope.launch {
|
||||
val auth = identityRepository.authToken.value.orEmpty()
|
||||
runCatching {
|
||||
try {
|
||||
communityRepository.block(
|
||||
id = id,
|
||||
blocked = false,
|
||||
@ -99,6 +102,9 @@ class ManageBanViewModel(
|
||||
updateState {
|
||||
it.copy(bannedCommunities = it.bannedCommunities.filter { e -> e.id != id })
|
||||
}
|
||||
emitEffect(ManageBanMviModel.Effect.Success)
|
||||
} catch (e: Throwable) {
|
||||
emitEffect(ManageBanMviModel.Effect.Failure(e.message))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,7 +112,7 @@ class ManageBanViewModel(
|
||||
private fun unbanInstance(id: Long) {
|
||||
screenModelScope.launch {
|
||||
val auth = identityRepository.authToken.value.orEmpty()
|
||||
runCatching {
|
||||
try {
|
||||
siteRepository.block(
|
||||
id = id,
|
||||
blocked = false,
|
||||
@ -115,6 +121,9 @@ class ManageBanViewModel(
|
||||
updateState {
|
||||
it.copy(bannedInstances = it.bannedInstances.filter { e -> e.id != id })
|
||||
}
|
||||
emitEffect(ManageBanMviModel.Effect.Success)
|
||||
} catch (e: Throwable) {
|
||||
emitEffect(ManageBanMviModel.Effect.Failure(e.message))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,9 @@ fun InstanceItem(
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = name,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = fullColor,
|
||||
)
|
||||
|
||||
|
@ -517,25 +517,39 @@ class PostListViewModel(
|
||||
|
||||
private fun blockUser(userId: Long) {
|
||||
screenModelScope.launch {
|
||||
val auth = identityRepository.authToken.value
|
||||
userRepository.block(userId, true, auth)
|
||||
runCatching {
|
||||
val auth = identityRepository.authToken.value
|
||||
userRepository.block(
|
||||
id = userId,
|
||||
blocked = true,
|
||||
auth = auth,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun blockCommunity(communityId: Long) {
|
||||
screenModelScope.launch {
|
||||
val auth = identityRepository.authToken.value
|
||||
communityRepository.block(communityId, true, auth)
|
||||
runCatching {
|
||||
val auth = identityRepository.authToken.value
|
||||
communityRepository.block(
|
||||
id = communityId,
|
||||
blocked = true,
|
||||
auth = auth,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun blockInstance(instanceId: Long) {
|
||||
screenModelScope.launch {
|
||||
try {
|
||||
runCatching {
|
||||
val auth = identityRepository.authToken.value
|
||||
siteRepository.block(instanceId, true, auth)
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
siteRepository.block(
|
||||
id = instanceId,
|
||||
blocked = true,
|
||||
auth = auth,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ class UserDetailScreen(
|
||||
this +=
|
||||
Option(
|
||||
OptionId.Block,
|
||||
LocalXmlStrings.current.communityDetailBlock,
|
||||
LocalXmlStrings.current.blockActionUser,
|
||||
)
|
||||
this +=
|
||||
Option(
|
||||
|
@ -536,7 +536,11 @@ class UserDetailViewModel(
|
||||
updateState { it.copy(asyncInProgress = true) }
|
||||
try {
|
||||
val auth = identityRepository.authToken.value
|
||||
userRepository.block(userId, true, auth).getOrThrow()
|
||||
userRepository.block(
|
||||
id = userId,
|
||||
blocked = true,
|
||||
auth = auth,
|
||||
)
|
||||
emitEffect(UserDetailMviModel.Effect.Success)
|
||||
} catch (e: Throwable) {
|
||||
emitEffect(UserDetailMviModel.Effect.Error(e.message))
|
||||
@ -553,7 +557,11 @@ class UserDetailViewModel(
|
||||
val user = uiState.value.user
|
||||
val instanceId = user.instanceId
|
||||
val auth = identityRepository.authToken.value
|
||||
siteRepository.block(instanceId, true, auth).getOrThrow()
|
||||
siteRepository.block(
|
||||
id = instanceId,
|
||||
blocked = true,
|
||||
auth = auth,
|
||||
)
|
||||
emitEffect(UserDetailMviModel.Effect.Success)
|
||||
} catch (e: Throwable) {
|
||||
emitEffect(UserDetailMviModel.Effect.Error(e.message))
|
||||
|
Loading…
x
Reference in New Issue
Block a user