refactor: main-safe repositories (#601)

This commit is contained in:
Diego Beraldin 2024-03-14 23:10:26 +01:00 committed by GitHub
parent c1e6f1a86f
commit f69738482e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 1090 additions and 957 deletions

View File

@ -3,6 +3,9 @@ package com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.LoginForm
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.LoginResponse
import com.github.diegoberaldin.raccoonforlemmy.core.api.provider.ServiceProvider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
internal class DefaultAuthRepository(
private val services: ServiceProvider,
@ -11,17 +14,19 @@ internal class DefaultAuthRepository(
username: String,
password: String,
totp2faToken: String?,
): Result<LoginResponse> = runCatching {
val data = LoginForm(
username = username,
password = password,
totp2faToken = totp2faToken,
)
val response = services.auth.login(data)
if (!response.isSuccessful) {
val error = response.errorBody().toString()
throw Exception(error)
): Result<LoginResponse> = withContext(Dispatchers.IO) {
runCatching {
val data = LoginForm(
username = username,
password = password,
totp2faToken = totp2faToken,
)
val response = services.auth.login(data)
if (!response.isSuccessful) {
val error = response.errorBody().toString()
throw Exception(error)
}
response.body() ?: throw Exception("No reponse from login endpoint")
}
response.body() ?: throw Exception("No reponse from login endpoint")
}
}

View File

@ -41,7 +41,12 @@ interface CommentRepository {
fun asUpVoted(comment: CommentModel, voted: Boolean): CommentModel
fun asUpVoted(mention: PersonMentionModel, voted: Boolean): PersonMentionModel
suspend fun upVote(comment: CommentModel, auth: String, voted: Boolean)
suspend fun upVote(
comment: CommentModel,
auth: String,
voted: Boolean,
): Result<Response<CommentResponse>>
fun asDownVoted(comment: CommentModel, downVoted: Boolean): CommentModel
fun asDownVoted(mention: PersonMentionModel, downVoted: Boolean): PersonMentionModel

View File

@ -19,6 +19,9 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.to
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toCommentDto
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toDto
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
internal class DefaultCommentRepository(
private val services: ServiceProvider,
@ -34,46 +37,50 @@ internal class DefaultCommentRepository(
type: ListingType,
sort: SortType,
maxDepth: Int,
): List<CommentModel>? = runCatching {
val response = if (instance.isNullOrEmpty()) {
services.comment.getAll(
authHeader = auth.toAuthHeader(),
auth = auth,
postId = postId,
page = page,
limit = limit,
type = type.toDto(),
sort = sort.toCommentDto(),
maxDepth = maxDepth,
)
} else {
customServices.changeInstance(instance)
customServices.comment.getAll(
postId = postId,
page = page,
limit = limit,
type = type.toDto(),
sort = sort.toCommentDto(),
maxDepth = maxDepth,
)
}
val dto = response.body()?.comments ?: emptyList()
dto.map { it.toModel() }
}.getOrNull()
override suspend fun getBy(id: Int, auth: String?, instance: String?): CommentModel? =
): List<CommentModel>? = withContext(Dispatchers.IO) {
runCatching {
if (instance.isNullOrEmpty()) {
services.comment.getBy(
val response = if (instance.isNullOrEmpty()) {
services.comment.getAll(
authHeader = auth.toAuthHeader(),
id = id,
auth = auth,
).body()
postId = postId,
page = page,
limit = limit,
type = type.toDto(),
sort = sort.toCommentDto(),
maxDepth = maxDepth,
)
} else {
customServices.changeInstance(instance)
customServices.comment.getBy(id = id).body()
}?.commentView?.toModel()
customServices.comment.getAll(
postId = postId,
page = page,
limit = limit,
type = type.toDto(),
sort = sort.toCommentDto(),
maxDepth = maxDepth,
)
}
val dto = response.body()?.comments ?: emptyList()
dto.map { it.toModel() }
}.getOrNull()
}
override suspend fun getBy(id: Int, auth: String?, instance: String?): CommentModel? =
withContext(Dispatchers.IO) {
runCatching {
if (instance.isNullOrEmpty()) {
services.comment.getBy(
authHeader = auth.toAuthHeader(),
id = id,
auth = auth,
).body()
} else {
customServices.changeInstance(instance)
customServices.comment.getBy(id = id).body()
}?.commentView?.toModel()
}.getOrNull()
}
override suspend fun getChildren(
parentId: Int,
@ -83,30 +90,32 @@ internal class DefaultCommentRepository(
type: ListingType,
sort: SortType,
maxDepth: Int,
): List<CommentModel>? = runCatching {
val response = if (instance.isNullOrEmpty()) {
services.comment.getAll(
authHeader = auth.toAuthHeader(),
auth = auth,
parentId = parentId,
limit = limit,
type = type.toDto(),
sort = sort.toCommentDto(),
maxDepth = maxDepth,
)
} else {
customServices.changeInstance(instance)
customServices.comment.getAll(
parentId = parentId,
limit = limit,
type = type.toDto(),
sort = sort.toCommentDto(),
maxDepth = maxDepth,
)
}
val dto = response.body()?.comments ?: emptyList()
dto.map { it.toModel() }
}.getOrNull()
): List<CommentModel>? = withContext(Dispatchers.IO) {
runCatching {
val response = if (instance.isNullOrEmpty()) {
services.comment.getAll(
authHeader = auth.toAuthHeader(),
auth = auth,
parentId = parentId,
limit = limit,
type = type.toDto(),
sort = sort.toCommentDto(),
maxDepth = maxDepth,
)
} else {
customServices.changeInstance(instance)
customServices.comment.getAll(
parentId = parentId,
limit = limit,
type = type.toDto(),
sort = sort.toCommentDto(),
maxDepth = maxDepth,
)
}
val dto = response.body()?.comments ?: emptyList()
dto.map { it.toModel() }
}.getOrNull()
}
override fun asUpVoted(comment: CommentModel, voted: Boolean) = comment.copy(
myVote = if (voted) 1 else 0,
@ -144,13 +153,19 @@ internal class DefaultCommentRepository(
}
)
override suspend fun upVote(comment: CommentModel, auth: String, voted: Boolean) {
val data = CreateCommentLikeForm(
commentId = comment.id,
score = if (voted) 1 else 0,
auth = auth,
)
services.comment.like(authHeader = auth.toAuthHeader(), form = data)
override suspend fun upVote(
comment: CommentModel,
auth: String,
voted: Boolean,
) = withContext(Dispatchers.IO) {
runCatching {
val data = CreateCommentLikeForm(
commentId = comment.id,
score = if (voted) 1 else 0,
auth = auth,
)
services.comment.like(authHeader = auth.toAuthHeader(), form = data)
}
}
override fun asDownVoted(comment: CommentModel, downVoted: Boolean) = comment.copy(
@ -190,13 +205,15 @@ internal class DefaultCommentRepository(
)
override suspend fun downVote(comment: CommentModel, auth: String, downVoted: Boolean) =
runCatching {
val data = CreateCommentLikeForm(
commentId = comment.id,
score = if (downVoted) -1 else 0,
auth = auth,
)
services.comment.like(authHeader = auth.toAuthHeader(), form = data)
withContext(Dispatchers.IO) {
runCatching {
val data = CreateCommentLikeForm(
commentId = comment.id,
score = if (downVoted) -1 else 0,
auth = auth,
)
services.comment.like(authHeader = auth.toAuthHeader(), form = data)
}
}
override fun asSaved(comment: CommentModel, saved: Boolean) = comment.copy(saved = saved)
@ -216,94 +233,107 @@ internal class DefaultCommentRepository(
text: String,
languageId: Int?,
auth: String,
) = runCatching {
val data = CreateCommentForm(
content = text,
postId = postId,
parentId = parentId,
languageId = languageId,
auth = auth,
)
services.comment.create(authHeader = auth.toAuthHeader(), form = data)
Unit
}.getOrDefault(Unit)
) = withContext(Dispatchers.IO) {
runCatching {
val data = CreateCommentForm(
content = text,
postId = postId,
parentId = parentId,
languageId = languageId,
auth = auth,
)
services.comment.create(authHeader = auth.toAuthHeader(), form = data)
Unit
}.getOrDefault(Unit)
}
override suspend fun edit(
commentId: Int,
text: String,
languageId: Int?,
auth: String,
) = runCatching {
val data = EditCommentForm(
content = text,
commentId = commentId,
languageId = languageId,
auth = auth,
)
services.comment.edit(authHeader = auth.toAuthHeader(), form = data)
Unit
}.getOrDefault(Unit)
) = withContext(Dispatchers.IO) {
runCatching {
val data = EditCommentForm(
content = text,
commentId = commentId,
languageId = languageId,
auth = auth,
)
services.comment.edit(authHeader = auth.toAuthHeader(), form = data)
Unit
}.getOrDefault(Unit)
}
override suspend fun delete(
commentId: Int,
auth: String,
) = runCatching {
val data = DeleteCommentForm(
commentId = commentId,
deleted = true,
)
services.comment.delete(authHeader = auth.toAuthHeader(), form = data)
Unit
}.getOrDefault(Unit)
) = withContext(Dispatchers.IO) {
runCatching {
val data = DeleteCommentForm(
commentId = commentId,
deleted = true,
)
services.comment.delete(authHeader = auth.toAuthHeader(), form = data)
Unit
}.getOrDefault(Unit)
}
override suspend fun report(commentId: Int, reason: String, auth: String) = runCatching {
val data = CreateCommentReportForm(
commentId = commentId,
reason = reason,
auth = auth,
)
services.comment.createReport(
form = data,
authHeader = auth.toAuthHeader(),
)
Unit
}.getOrDefault(Unit)
override suspend fun report(commentId: Int, reason: String, auth: String) =
withContext(Dispatchers.IO) {
runCatching {
val data = CreateCommentReportForm(
commentId = commentId,
reason = reason,
auth = auth,
)
services.comment.createReport(
form = data,
authHeader = auth.toAuthHeader(),
)
Unit
}.getOrDefault(Unit)
}
override suspend fun remove(
commentId: Int,
auth: String,
removed: Boolean,
reason: String,
): CommentModel? = runCatching {
val data = RemoveCommentForm(
commentId = commentId,
removed = removed,
reason = reason,
auth = auth,
)
val response = services.comment.remove(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.commentView?.toModel()
}.getOrNull()
): CommentModel? = withContext(Dispatchers.IO) {
runCatching {
val data = RemoveCommentForm(
commentId = commentId,
removed = removed,
reason = reason,
auth = auth,
)
val response = services.comment.remove(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.commentView?.toModel()
}.getOrNull()
}
override suspend fun distinguish(
commentId: Int,
auth: String,
distinguished: Boolean,
): CommentModel? = runCatching {
val data = DistinguishCommentForm(
commentId = commentId,
distinguished = distinguished,
auth = auth,
)
val response = services.comment.distinguish(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.commentView?.toModel()
}.getOrNull()
): CommentModel? = withContext(Dispatchers.IO) {
runCatching {
val data = DistinguishCommentForm(
commentId = commentId,
distinguished = distinguished,
auth = auth,
)
val response = services.comment.distinguish(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.commentView?.toModel()
}.getOrNull()
}
override suspend fun getReports(
auth: String,
@ -311,34 +341,38 @@ internal class DefaultCommentRepository(
page: Int,
limit: Int,
unresolvedOnly: Boolean,
): List<CommentReportModel>? = runCatching {
val response = services.comment.listReports(
authHeader = auth.toAuthHeader(),
auth = auth,
communityId = communityId,
page = page,
limit = limit,
unresolvedOnly = unresolvedOnly
)
response.body()?.commentReports?.map {
it.toModel()
}
}.getOrNull()
): List<CommentReportModel>? = withContext(Dispatchers.IO) {
runCatching {
val response = services.comment.listReports(
authHeader = auth.toAuthHeader(),
auth = auth,
communityId = communityId,
page = page,
limit = limit,
unresolvedOnly = unresolvedOnly
)
response.body()?.commentReports?.map {
it.toModel()
}
}.getOrNull()
}
override suspend fun resolveReport(
reportId: Int,
auth: String,
resolved: Boolean,
): CommentReportModel? = runCatching {
val data = ResolveCommentReportForm(
reportId = reportId,
resolved = resolved,
auth = auth,
)
val response = services.comment.resolveReport(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.commentReportView?.toModel()
}.getOrNull()
): CommentReportModel? = withContext(Dispatchers.IO) {
runCatching {
val data = ResolveCommentReportForm(
reportId = reportId,
resolved = resolved,
auth = auth,
)
val response = services.comment.resolveReport(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.commentReportView?.toModel()
}.getOrNull()
}
}

View File

@ -14,6 +14,9 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toAuthHeader
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toDto
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
internal class DefaultCommunityRepository(
private val services: ServiceProvider,
@ -29,152 +32,170 @@ internal class DefaultCommunityRepository(
listingType: ListingType,
sortType: SortType,
resultType: SearchResultType,
): List<SearchResult> = runCatching {
val searchResponse = services.search.search(
authHeader = auth.toAuthHeader(),
q = query,
auth = auth,
page = page,
limit = limit,
communityId = communityId,
type = resultType.toDto(),
listingType = listingType.toDto(),
sort = sortType.toDto(),
).body()
buildList<SearchResult> {
val posts = searchResponse?.posts?.map { it.toModel() }.orEmpty()
this += posts.map { SearchResult.Post(it) }
): List<SearchResult> = withContext(Dispatchers.IO) {
runCatching {
val searchResponse = services.search.search(
authHeader = auth.toAuthHeader(),
q = query,
auth = auth,
page = page,
limit = limit,
communityId = communityId,
type = resultType.toDto(),
listingType = listingType.toDto(),
sort = sortType.toDto(),
).body()
buildList<SearchResult> {
val posts = searchResponse?.posts?.map { it.toModel() }.orEmpty()
this += posts.map { SearchResult.Post(it) }
val comments = searchResponse?.comments?.map { it.toModel() }.orEmpty()
this += comments.map { SearchResult.Comment(it) }
val comments = searchResponse?.comments?.map { it.toModel() }.orEmpty()
this += comments.map { SearchResult.Comment(it) }
val communities = searchResponse?.communities?.map { it.toModel() }.orEmpty()
this += communities.map { SearchResult.Community(it) }
val communities = searchResponse?.communities?.map { it.toModel() }.orEmpty()
this += communities.map { SearchResult.Community(it) }
val users = searchResponse?.users?.map { it.toModel() }.orEmpty()
this += users.map { SearchResult.User(it) }
}
}.getOrElse { emptyList() }
val users = searchResponse?.users?.map { it.toModel() }.orEmpty()
this += users.map { SearchResult.User(it) }
}
}.getOrElse { emptyList() }
}
override suspend fun getList(
instance: String,
page: Int,
limit: Int,
sortType: SortType,
): List<CommunityModel> = runCatching {
customServices.changeInstance(instance)
val response = customServices.community.getAll(
page = page,
limit = limit,
sort = sortType.toDto(),
).body()
response?.communities?.map {
it.toModel()
}.orEmpty()
}.getOrElse { emptyList() }
): List<CommunityModel> = withContext(Dispatchers.IO) {
runCatching {
customServices.changeInstance(instance)
val response = customServices.community.getAll(
page = page,
limit = limit,
sort = sortType.toDto(),
).body()
response?.communities?.map {
it.toModel()
}.orEmpty()
}.getOrElse { emptyList() }
}
override suspend fun getResolved(
query: String,
auth: String?,
): CommunityModel? = runCatching {
val resolveResponse = services.search.resolveObject(
authHeader = auth.toAuthHeader(),
q = query
).body()
resolveResponse?.community?.toModel()
}.getOrNull()
): CommunityModel? = withContext(Dispatchers.IO) {
runCatching {
val resolveResponse = services.search.resolveObject(
authHeader = auth.toAuthHeader(),
q = query
).body()
resolveResponse?.community?.toModel()
}.getOrNull()
}
override suspend fun getSubscribed(
auth: String?,
): List<CommunityModel> = runCatching {
val response = services.site.get(
authHeader = auth.toAuthHeader(),
auth = auth,
).body()
response?.myUser?.follows?.map { it.community.toModel() }.orEmpty()
}.getOrElse { emptyList() }
): List<CommunityModel> = withContext(Dispatchers.IO) {
runCatching {
val response = services.site.get(
authHeader = auth.toAuthHeader(),
auth = auth,
).body()
response?.myUser?.follows?.map { it.community.toModel() }.orEmpty()
}.getOrElse { emptyList() }
}
override suspend fun get(
auth: String?,
id: Int?,
name: String?,
instance: String?,
): CommunityModel? = runCatching {
val response = if (instance.isNullOrEmpty()) {
services.community.get(
authHeader = auth.toAuthHeader(),
auth = auth,
id = id,
name = name,
).body()
} else {
customServices.changeInstance(instance)
customServices.community.get(name = name).body()
}
response?.communityView?.toModel()
}.getOrNull()
): CommunityModel? = withContext(Dispatchers.IO) {
runCatching {
val response = if (instance.isNullOrEmpty()) {
services.community.get(
authHeader = auth.toAuthHeader(),
auth = auth,
id = id,
name = name,
).body()
} else {
customServices.changeInstance(instance)
customServices.community.get(name = name).body()
}
response?.communityView?.toModel()
}.getOrNull()
}
override suspend fun getModerators(
auth: String?,
id: Int?,
): List<UserModel> = runCatching {
val response = services.community.get(
authHeader = auth.toAuthHeader(),
auth = auth,
id = id,
).body()
response?.moderators?.map {
it.moderator.toModel()
}.orEmpty()
}.getOrElse { emptyList() }
): List<UserModel> = withContext(Dispatchers.IO) {
runCatching {
val response = services.community.get(
authHeader = auth.toAuthHeader(),
auth = auth,
id = id,
).body()
response?.moderators?.map {
it.moderator.toModel()
}.orEmpty()
}.getOrElse { emptyList() }
}
override suspend fun subscribe(
auth: String?,
id: Int,
): CommunityModel? = runCatching {
val data = FollowCommunityForm(
auth = auth.orEmpty(),
communityId = id,
follow = true,
)
val response = services.community.follow(
authHeader = auth.toAuthHeader(),
form = data
)
response.body()?.communityView?.toModel()
}.getOrNull()
): CommunityModel? = withContext(Dispatchers.IO) {
runCatching {
val data = FollowCommunityForm(
auth = auth.orEmpty(),
communityId = id,
follow = true,
)
val response = services.community.follow(
authHeader = auth.toAuthHeader(),
form = data
)
response.body()?.communityView?.toModel()
}.getOrNull()
}
override suspend fun unsubscribe(
auth: String?,
id: Int,
): CommunityModel? = runCatching {
val data = FollowCommunityForm(
auth = auth.orEmpty(),
communityId = id,
follow = false,
)
val response = services.community.follow(
authHeader = auth.toAuthHeader(),
form = data
)
response.body()?.communityView?.toModel()
}.getOrNull()
): CommunityModel? = withContext(Dispatchers.IO) {
runCatching {
val data = FollowCommunityForm(
auth = auth.orEmpty(),
communityId = id,
follow = false,
)
val response = services.community.follow(
authHeader = auth.toAuthHeader(),
form = data
)
response.body()?.communityView?.toModel()
}.getOrNull()
}
override suspend fun block(
id: Int,
blocked: Boolean,
auth: String?,
): Result<Unit> = runCatching {
val data = BlockCommunityForm(
communityId = id,
block = blocked,
auth = auth.orEmpty(),
)
services.community.block(
authHeader = auth.toAuthHeader(),
form = data,
)
Unit
): Result<Unit> = withContext(Dispatchers.IO) {
runCatching {
val data = BlockCommunityForm(
communityId = id,
block = blocked,
auth = auth.orEmpty(),
)
services.community.block(
authHeader = auth.toAuthHeader(),
form = data,
)
Unit
}
}
override suspend fun banUser(
@ -185,41 +206,45 @@ internal class DefaultCommunityRepository(
removeData: Boolean,
reason: String?,
expires: Long?,
): UserModel? = runCatching {
val data = BanFromCommunityForm(
auth = auth.orEmpty(),
ban = ban,
removeData = removeData,
personId = userId,
communityId = communityId,
reason = reason,
expires = expires,
)
val response = services.community.ban(
authHeader = auth.toAuthHeader(),
form = data,
)
response.body()?.personView?.toModel()?.copy(banned = ban)
}.getOrNull()
): UserModel? = withContext(Dispatchers.IO) {
runCatching {
val data = BanFromCommunityForm(
auth = auth.orEmpty(),
ban = ban,
removeData = removeData,
personId = userId,
communityId = communityId,
reason = reason,
expires = expires,
)
val response = services.community.ban(
authHeader = auth.toAuthHeader(),
form = data,
)
response.body()?.personView?.toModel()?.copy(banned = ban)
}.getOrNull()
}
override suspend fun addModerator(
auth: String?,
communityId: Int,
userId: Int,
added: Boolean,
): List<UserModel> = runCatching {
val data = AddModToCommunityForm(
auth = auth.orEmpty(),
added = added,
personId = userId,
communityId = communityId,
)
val response = services.community.addMod(
authHeader = auth.toAuthHeader(),
form = data,
).body()
response?.moderators?.map {
it.moderator.toModel()
}.orEmpty()
}.getOrElse { emptyList() }
): List<UserModel> = withContext(Dispatchers.IO) {
runCatching {
val data = AddModToCommunityForm(
auth = auth.orEmpty(),
added = added,
personId = userId,
communityId = communityId,
)
val response = services.community.addMod(
authHeader = auth.toAuthHeader(),
form = data,
).body()
response?.moderators?.map {
it.moderator.toModel()
}.orEmpty()
}.getOrElse { emptyList() }
}
}

View File

@ -5,6 +5,9 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
internal class DefaultLemmyItemCache(
private val postCache: LruCache<PostModel>,
@ -13,27 +16,27 @@ internal class DefaultLemmyItemCache(
private val userCache: LruCache<UserModel>,
) : LemmyItemCache {
override suspend fun putPost(value: PostModel) {
override suspend fun putPost(value: PostModel) = withContext(Dispatchers.IO) {
postCache.put(value = value, key = value.id)
}
override suspend fun getPost(id: Int): PostModel? = postCache.get(id)
override suspend fun getPost(id: Int): PostModel? = withContext(Dispatchers.IO) { postCache.get(id) }
override suspend fun putComment(value: CommentModel) {
override suspend fun putComment(value: CommentModel) = withContext(Dispatchers.IO) {
commentCache.put(value = value, key = value.id)
}
override suspend fun getComment(id: Int): CommentModel? = commentCache.get(id)
override suspend fun getComment(id: Int): CommentModel? = withContext(Dispatchers.IO) { commentCache.get(id) }
override suspend fun putCommunity(value: CommunityModel) {
override suspend fun putCommunity(value: CommunityModel) = withContext(Dispatchers.IO) {
communityCache.put(value = value, key = value.id)
}
override suspend fun getCommunity(id: Int): CommunityModel? = communityCache.get(id)
override suspend fun getCommunity(id: Int): CommunityModel? = withContext(Dispatchers.IO) { communityCache.get(id) }
override suspend fun putUser(value: UserModel) {
override suspend fun putUser(value: UserModel) = withContext(Dispatchers.IO) {
userCache.put(value = value, key = value.id)
}
override suspend fun getUser(id: Int): UserModel? = userCache.get(id)
override suspend fun getUser(id: Int): UserModel? = withContext(Dispatchers.IO) { userCache.get(id) }
}

View File

@ -5,6 +5,9 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ModlogItem
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ModlogItemType
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toAuthHeader
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toDto
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
internal class DefaultModlogRepository(
private val services: ServiceProvider,
@ -15,25 +18,27 @@ internal class DefaultModlogRepository(
limit: Int,
page: Int,
type: ModlogItemType,
): List<ModlogItem>? = runCatching {
val response = services.modLog.getItems(
authHeader = auth.toAuthHeader(),
auth = auth,
communityId = communityId,
limit = limit,
page = page,
type = type.toDto(),
)
val dto = response.body() ?: return@runCatching null
val result = buildList<ModlogItem> {
this += dto.addedToCommunity?.map { it.toDto() }.orEmpty()
this += dto.bannedFromCommunity?.map { it.toDto() }.orEmpty()
this += dto.featuredPosts?.map { it.toDto() }.orEmpty()
this += dto.lockedPosts?.map { it.toDto() }.orEmpty()
this += dto.removedPosts?.map { it.toDto() }.orEmpty()
this += dto.removedComments?.map { it.toDto() }.orEmpty()
this += dto.transferredToCommunity?.map { it.toDto() }.orEmpty()
}
result.sortedByDescending { it.date }
}.getOrNull()
): List<ModlogItem>? = withContext(Dispatchers.IO) {
runCatching {
val response = services.modLog.getItems(
authHeader = auth.toAuthHeader(),
auth = auth,
communityId = communityId,
limit = limit,
page = page,
type = type.toDto(),
)
val dto = response.body() ?: return@runCatching null
val result = buildList<ModlogItem> {
this += dto.addedToCommunity?.map { it.toDto() }.orEmpty()
this += dto.bannedFromCommunity?.map { it.toDto() }.orEmpty()
this += dto.featuredPosts?.map { it.toDto() }.orEmpty()
this += dto.lockedPosts?.map { it.toDto() }.orEmpty()
this += dto.removedPosts?.map { it.toDto() }.orEmpty()
this += dto.removedComments?.map { it.toDto() }.orEmpty()
this += dto.transferredToCommunity?.map { it.toDto() }.orEmpty()
}
result.sortedByDescending { it.date }
}.getOrNull()
}
}

View File

@ -20,10 +20,12 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toAuthHeader
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toDto
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
import io.ktor.client.request.forms.MultiPartFormDataContent
import io.ktor.client.request.forms.formData
import io.ktor.client.request.forms.*
import io.ktor.http.Headers
import io.ktor.http.HttpHeaders
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
internal class DefaultPostRepository(
private val services: ServiceProvider,
@ -40,54 +42,58 @@ internal class DefaultPostRepository(
communityId: Int?,
communityName: String?,
otherInstance: String?,
): Pair<List<PostModel>, String?>? = runCatching {
val response = if (otherInstance.isNullOrEmpty()) {
services.post.getAll(
authHeader = auth.toAuthHeader(),
auth = auth,
communityId = communityId,
page = if (pageCursor.isNullOrEmpty()) page else null,
pageCursor = pageCursor,
limit = limit,
type = type.toDto(),
sort = sort.toDto(),
)
} else {
customServices.changeInstance(otherInstance)
customServices.post.getAll(
communityName = communityName,
page = if (pageCursor.isNullOrEmpty()) page else null,
pageCursor = pageCursor,
limit = limit,
type = type.toDto(),
sort = sort.toDto(),
)
}
val body = response.body()
val posts = body?.posts?.map { it.toModel() } ?: emptyList()
posts to body?.nextPage
}.getOrNull()
): Pair<List<PostModel>, String?>? = withContext(Dispatchers.IO) {
runCatching {
val response = if (otherInstance.isNullOrEmpty()) {
services.post.getAll(
authHeader = auth.toAuthHeader(),
auth = auth,
communityId = communityId,
page = if (pageCursor.isNullOrEmpty()) page else null,
pageCursor = pageCursor,
limit = limit,
type = type.toDto(),
sort = sort.toDto(),
)
} else {
customServices.changeInstance(otherInstance)
customServices.post.getAll(
communityName = communityName,
page = if (pageCursor.isNullOrEmpty()) page else null,
pageCursor = pageCursor,
limit = limit,
type = type.toDto(),
sort = sort.toDto(),
)
}
val body = response.body()
val posts = body?.posts?.map { it.toModel() } ?: emptyList()
posts to body?.nextPage
}.getOrNull()
}
override suspend fun get(
id: Int,
auth: String?,
instance: String?,
): PostModel? = runCatching {
val response = if (instance.isNullOrEmpty()) {
services.post.get(
authHeader = auth.toAuthHeader(),
auth = auth,
id = id,
).body()
} else {
customServices.changeInstance(instance)
customServices.post.get(id = id).body()
}
val dto = response?.postView
dto?.toModel()?.copy(
crossPosts = response.crossPosts.map { it.toModel() }
)
}.getOrNull()
): PostModel? = withContext(Dispatchers.IO) {
runCatching {
val response = if (instance.isNullOrEmpty()) {
services.post.get(
authHeader = auth.toAuthHeader(),
auth = auth,
id = id,
).body()
} else {
customServices.changeInstance(instance)
customServices.post.get(id = id).body()
}
val dto = response?.postView
dto?.toModel()?.copy(
crossPosts = response.crossPosts.map { it.toModel() }
)
}.getOrNull()
}
override fun asUpVoted(post: PostModel, voted: Boolean) = post.copy(
myVote = if (voted) 1 else 0,
@ -107,16 +113,18 @@ internal class DefaultPostRepository(
}
)
override suspend fun upVote(post: PostModel, auth: String, voted: Boolean) = runCatching {
val data = CreatePostLikeForm(
postId = post.id,
score = if (voted) 1 else 0,
auth = auth,
)
services.post.like(
authHeader = auth.toAuthHeader(),
form = data,
)
override suspend fun upVote(post: PostModel, auth: String, voted: Boolean) = withContext(Dispatchers.IO) {
runCatching {
val data = CreatePostLikeForm(
postId = post.id,
score = if (voted) 1 else 0,
auth = auth,
)
services.post.like(
authHeader = auth.toAuthHeader(),
form = data,
)
}
}
override fun asDownVoted(post: PostModel, downVoted: Boolean) = post.copy(
@ -137,30 +145,34 @@ internal class DefaultPostRepository(
}
)
override suspend fun downVote(post: PostModel, auth: String, downVoted: Boolean) = runCatching {
val data = CreatePostLikeForm(
postId = post.id,
score = if (downVoted) -1 else 0,
auth = auth,
)
services.post.like(
authHeader = auth.toAuthHeader(),
form = data,
)
override suspend fun downVote(post: PostModel, auth: String, downVoted: Boolean) = withContext(Dispatchers.IO) {
runCatching {
val data = CreatePostLikeForm(
postId = post.id,
score = if (downVoted) -1 else 0,
auth = auth,
)
services.post.like(
authHeader = auth.toAuthHeader(),
form = data,
)
}
}
override fun asSaved(post: PostModel, saved: Boolean): PostModel = post.copy(saved = saved)
override suspend fun save(post: PostModel, auth: String, saved: Boolean) = runCatching {
val data = SavePostForm(
postId = post.id,
save = saved,
auth = auth,
)
services.post.save(
authHeader = auth.toAuthHeader(),
form = data,
)
override suspend fun save(post: PostModel, auth: String, saved: Boolean) = withContext(Dispatchers.IO) {
runCatching {
val data = SavePostForm(
postId = post.id,
save = saved,
auth = auth,
)
services.post.save(
authHeader = auth.toAuthHeader(),
form = data,
)
}
}
override suspend fun create(
@ -171,22 +183,23 @@ internal class DefaultPostRepository(
nsfw: Boolean,
languageId: Int?,
auth: String,
) = runCatching {
val data = CreatePostForm(
communityId = communityId,
name = title,
body = body,
url = url,
nsfw = nsfw,
languageId = languageId,
auth = auth,
)
services.post.create(
authHeader = auth.toAuthHeader(),
form = data,
)
Unit
}.getOrDefault(Unit)
): Unit = withContext(Dispatchers.IO) {
runCatching {
val data = CreatePostForm(
communityId = communityId,
name = title,
body = body,
url = url,
nsfw = nsfw,
languageId = languageId,
auth = auth,
)
services.post.create(
authHeader = auth.toAuthHeader(),
form = data,
)
}.getOrDefault(Unit)
}
override suspend fun edit(
postId: Int,
@ -196,118 +209,130 @@ internal class DefaultPostRepository(
nsfw: Boolean,
languageId: Int?,
auth: String,
) = runCatching {
val data = EditPostForm(
postId = postId,
name = title,
body = body,
url = url,
nsfw = nsfw,
languageId = languageId,
auth = auth,
)
services.post.edit(
authHeader = auth.toAuthHeader(),
form = data,
)
Unit
}.getOrDefault(Unit)
override suspend fun setRead(read: Boolean, postId: Int, auth: String?) = runCatching {
val data = MarkPostAsReadForm(
postId = postId,
read = read,
auth = auth.orEmpty(),
)
services.post.markAsRead(
authHeader = auth.toAuthHeader(),
form = data,
)
): Unit = withContext(Dispatchers.IO) {
runCatching {
val data = EditPostForm(
postId = postId,
name = title,
body = body,
url = url,
nsfw = nsfw,
languageId = languageId,
auth = auth,
)
services.post.edit(
authHeader = auth.toAuthHeader(),
form = data,
)
}.getOrDefault(Unit)
}
override suspend fun delete(id: Int, auth: String) = runCatching {
val data = DeletePostForm(
postId = id,
deleted = true,
)
services.post.delete(
authHeader = auth.toAuthHeader(),
form = data,
)
Unit
}.apply {
exceptionOrNull()?.also {
it.printStackTrace()
override suspend fun setRead(read: Boolean, postId: Int, auth: String?) = withContext(Dispatchers.IO) {
runCatching {
val data = MarkPostAsReadForm(
postId = postId,
read = read,
auth = auth.orEmpty(),
)
services.post.markAsRead(
authHeader = auth.toAuthHeader(),
form = data,
)
}
}.getOrDefault(Unit)
}
override suspend fun uploadImage(auth: String, bytes: ByteArray): String? = runCatching {
val url = "https://${services.currentInstance}/pictrs/image"
val multipart = MultiPartFormDataContent(formData {
append(key = "images[]", value = bytes, headers = Headers.build {
append(HttpHeaders.ContentType, "image/*")
append(HttpHeaders.ContentDisposition, "filename=image.jpeg")
override suspend fun delete(id: Int, auth: String): Unit = withContext(Dispatchers.IO) {
runCatching {
val data = DeletePostForm(
postId = id,
deleted = true,
)
services.post.delete(
authHeader = auth.toAuthHeader(),
form = data,
)
}.apply {
exceptionOrNull()?.also {
it.printStackTrace()
}
}.getOrDefault(Unit)
}
override suspend fun uploadImage(auth: String, bytes: ByteArray): String? = withContext(Dispatchers.IO) {
runCatching {
val url = "https://${services.currentInstance}/pictrs/image"
val multipart = MultiPartFormDataContent(formData {
append(key = "images[]", value = bytes, headers = Headers.build {
append(HttpHeaders.ContentType, "image/*")
append(HttpHeaders.ContentDisposition, "filename=image.jpeg")
})
})
})
val images = services.post.uploadImage(
url = url,
token = "jwt=$auth",
authHeader = auth.toAuthHeader(),
content = multipart,
).body()
"$url/${images?.files?.firstOrNull()?.file}"
}.apply {
exceptionOrNull()?.also {
it.printStackTrace()
}
}.getOrNull()
val images = services.post.uploadImage(
url = url,
token = "jwt=$auth",
authHeader = auth.toAuthHeader(),
content = multipart,
).body()
"$url/${images?.files?.firstOrNull()?.file}"
}.apply {
exceptionOrNull()?.also {
it.printStackTrace()
}
}.getOrNull()
}
override suspend fun report(postId: Int, reason: String, auth: String) {
val data = CreatePostReportForm(
postId = postId,
reason = reason,
auth = auth,
)
services.post.createReport(
form = data,
authHeader = auth.toAuthHeader(),
)
override suspend fun report(postId: Int, reason: String, auth: String): Unit = withContext(Dispatchers.IO) {
runCatching {
val data = CreatePostReportForm(
postId = postId,
reason = reason,
auth = auth,
)
services.post.createReport(
form = data,
authHeader = auth.toAuthHeader(),
)
}
}
override suspend fun featureInCommunity(
postId: Int,
auth: String,
featured: Boolean,
): PostModel? = runCatching {
val data = FeaturePostForm(
postId = postId,
auth = auth,
featured = featured,
featureType = PostFeatureType.Community,
)
val response = services.post.feature(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.postView?.toModel()
}.getOrNull()
): PostModel? = withContext(Dispatchers.IO) {
runCatching {
val data = FeaturePostForm(
postId = postId,
auth = auth,
featured = featured,
featureType = PostFeatureType.Community,
)
val response = services.post.feature(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.postView?.toModel()
}.getOrNull()
}
override suspend fun lock(
postId: Int,
auth: String,
locked: Boolean,
): PostModel? = runCatching {
val data = LockPostForm(
postId = postId,
auth = auth,
locked = locked,
)
val response = services.post.lock(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.postView?.toModel()
}.getOrNull()
): PostModel? = withContext(Dispatchers.IO) {
runCatching {
val data = LockPostForm(
postId = postId,
auth = auth,
locked = locked,
)
val response = services.post.lock(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.postView?.toModel()
}.getOrNull()
}
override suspend fun remove(
postId: Int,
@ -334,34 +359,38 @@ internal class DefaultPostRepository(
page: Int,
limit: Int,
unresolvedOnly: Boolean,
): List<PostReportModel>? = runCatching {
val response = services.post.listReports(
authHeader = auth.toAuthHeader(),
auth = auth,
communityId = communityId,
page = page,
limit = limit,
unresolvedOnly = unresolvedOnly
)
response.body()?.postReports?.map {
it.toModel()
}
}.getOrNull()
): List<PostReportModel>? = withContext(Dispatchers.IO) {
runCatching {
val response = services.post.listReports(
authHeader = auth.toAuthHeader(),
auth = auth,
communityId = communityId,
page = page,
limit = limit,
unresolvedOnly = unresolvedOnly
)
response.body()?.postReports?.map {
it.toModel()
}
}.getOrNull()
}
override suspend fun resolveReport(
reportId: Int,
auth: String,
resolved: Boolean,
): PostReportModel? = runCatching {
val data = ResolvePostReportForm(
reportId = reportId,
auth = auth,
resolved = resolved,
)
val response = services.post.resolveReport(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.postReportView?.toModel()
}.getOrNull()
): PostReportModel? = withContext(Dispatchers.IO) {
runCatching {
val data = ResolvePostReportForm(
reportId = reportId,
auth = auth,
resolved = resolved,
)
val response = services.post.resolveReport(
form = data,
authHeader = auth.toAuthHeader(),
)
response.body()?.postReportView?.toModel()
}.getOrNull()
}
}

View File

@ -8,6 +8,9 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.provider.ServiceProvide
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PrivateMessageModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toAuthHeader
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
internal class DefaultPrivateMessageRepository(
private val services: ServiceProvider,
@ -19,35 +22,39 @@ internal class DefaultPrivateMessageRepository(
page: Int,
limit: Int,
unreadOnly: Boolean,
): List<PrivateMessageModel>? = runCatching {
val response = services.privateMessages.getAll(
authHeader = auth.toAuthHeader(),
auth = auth,
creatorId = creatorId,
limit = limit,
page = page,
unreadOnly = unreadOnly,
)
val dto = response.body() ?: return@runCatching emptyList()
dto.privateMessages.map { it.toModel() }
}.getOrNull()
): List<PrivateMessageModel>? = withContext(Dispatchers.IO) {
runCatching {
val response = services.privateMessages.getAll(
authHeader = auth.toAuthHeader(),
auth = auth,
creatorId = creatorId,
limit = limit,
page = page,
unreadOnly = unreadOnly,
)
val dto = response.body() ?: return@runCatching emptyList()
dto.privateMessages.map { it.toModel() }
}.getOrNull()
}
override suspend fun create(
message: String,
auth: String?,
recipientId: Int,
): PrivateMessageModel? = runCatching {
val data = CreatePrivateMessageForm(
content = message,
auth = auth.orEmpty(),
recipientId = recipientId,
)
val dto = services.privateMessages.create(
authHeader = auth.toAuthHeader(),
form = data,
).body()
dto?.privateMessageView?.toModel()
}.getOrNull()
): PrivateMessageModel? = withContext(Dispatchers.IO) {
runCatching {
val data = CreatePrivateMessageForm(
content = message,
auth = auth.orEmpty(),
recipientId = recipientId,
)
val dto = services.privateMessages.create(
authHeader = auth.toAuthHeader(),
form = data,
).body()
dto?.privateMessageView?.toModel()
}.getOrNull()
}
override suspend fun edit(
messageId: Int,
@ -70,29 +77,32 @@ internal class DefaultPrivateMessageRepository(
messageId: Int,
auth: String?,
read: Boolean,
): PrivateMessageModel? = runCatching {
val data = MarkPrivateMessageAsReadForm(
privateMessageId = messageId,
auth = auth.orEmpty(),
read = read,
)
val dto = services.privateMessages.markAsRead(
authHeader = auth.toAuthHeader(),
form = data,
)
return dto.body()?.privateMessageView?.toModel()
}.getOrNull()
): PrivateMessageModel? = withContext(Dispatchers.IO) {
runCatching {
val data = MarkPrivateMessageAsReadForm(
privateMessageId = messageId,
auth = auth.orEmpty(),
read = read,
)
val dto = services.privateMessages.markAsRead(
authHeader = auth.toAuthHeader(),
form = data,
)
dto.body()?.privateMessageView?.toModel()
}.getOrNull()
}
override suspend fun delete(messageId: Int, auth: String?) = runCatching {
val data = DeletePrivateMessageForm(
auth = auth.orEmpty(),
privateMessageId = messageId,
deleted = true,
)
services.privateMessages.delete(
authHeader = auth.toAuthHeader(),
form = data,
)
Unit
}.getOrDefault(Unit)
override suspend fun delete(messageId: Int, auth: String?): Unit = withContext(Dispatchers.IO) {
runCatching {
val data = DeletePrivateMessageForm(
auth = auth.orEmpty(),
privateMessageId = messageId,
deleted = true,
)
services.privateMessages.delete(
authHeader = auth.toAuthHeader(),
form = data,
)
}.getOrDefault(Unit)
}
}

View File

@ -10,24 +10,29 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toAuthHeader
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toDto
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
internal class DefaultSiteRepository(
private val services: ServiceProvider,
private val customServices: ServiceProvider,
) : SiteRepository {
override suspend fun getCurrentUser(auth: String): UserModel? = runCatching {
val dto = services.site.get(
auth = auth,
authHeader = auth.toAuthHeader(),
).body()
dto?.myUser?.let {
val user = it.localUserView?.person
val counts = it.localUserView?.counts
user?.toModel()?.copy(score = counts?.toModel())
}
}.getOrNull()
override suspend fun getCurrentUser(auth: String): UserModel? = withContext(Dispatchers.IO) {
runCatching {
val dto = services.site.get(
auth = auth,
authHeader = auth.toAuthHeader(),
).body()
dto?.myUser?.let {
val user = it.localUserView?.person
val counts = it.localUserView?.counts
user?.toModel()?.copy(score = counts?.toModel())
}
}.getOrNull()
}
override suspend fun getSiteVersion(auth: String?, otherInstance: String?): String? =
override suspend fun getSiteVersion(auth: String?, otherInstance: String?): String? = withContext(Dispatchers.IO) {
runCatching {
if (otherInstance.isNullOrEmpty()) {
val dto = services.site.get(
@ -42,8 +47,9 @@ internal class DefaultSiteRepository(
dto?.version.takeIf { !it.isNullOrEmpty() }
}
}.getOrNull()
}
override suspend fun block(id: Int, blocked: Boolean, auth: String?): Result<Unit> =
override suspend fun block(id: Int, blocked: Boolean, auth: String?): Result<Unit> = withContext(Dispatchers.IO) {
runCatching {
val data = BlockSiteForm(
instanceId = id,
@ -55,60 +61,71 @@ internal class DefaultSiteRepository(
)
Unit
}
}
override suspend fun getMetadata(url: String): MetadataModel? = runCatching {
val response = services.post.getSiteMetadata(
url = url,
)
response.body()?.metadata?.toModel()
}.getOrNull()
override suspend fun getLanguages(auth: String?): List<LanguageModel> = runCatching {
val response = services.site.get(auth = auth)
val dto = response.body()
dto?.allLanguages?.map { it.toModel() }.orEmpty()
}.getOrElse { emptyList() }
override suspend fun getAccountSettings(auth: String): AccountSettingsModel? = runCatching {
val dto = services.site.get(
auth = auth,
authHeader = auth.toAuthHeader(),
).body()
dto?.myUser?.localUserView?.run {
localUser?.toModel()?.copy(
avatar = person.avatar,
banner = person.banner,
bio = person.bio,
bot = person.botAccount,
displayName = person.displayName,
matrixUserId = person.matrixUserId,
override suspend fun getMetadata(url: String): MetadataModel? = withContext(Dispatchers.IO) {
runCatching {
val response = services.post.getSiteMetadata(
url = url,
)
}
}.getOrNull()
response.body()?.metadata?.toModel()
}.getOrNull()
}
override suspend fun getLanguages(auth: String?): List<LanguageModel> = withContext(Dispatchers.IO) {
runCatching {
val response = services.site.get(auth = auth)
val dto = response.body()
dto?.allLanguages?.map { it.toModel() }.orEmpty()
}.getOrElse { emptyList() }
}
override suspend fun getAccountSettings(auth: String): AccountSettingsModel? = withContext(Dispatchers.IO) {
runCatching {
val dto = services.site.get(
auth = auth,
authHeader = auth.toAuthHeader(),
).body()
dto?.myUser?.localUserView?.run {
localUser?.toModel()?.copy(
avatar = person.avatar,
banner = person.banner,
bio = person.bio,
bot = person.botAccount,
displayName = person.displayName,
matrixUserId = person.matrixUserId,
)
}
}.getOrNull()
}
override suspend fun updateAccountSettings(
auth: String,
value: AccountSettingsModel,
) = runCatching {
val formData = value.toDto().copy(auth = auth)
services.user.saveUserSettings(
authHeader = auth.toAuthHeader(),
form = formData,
)
Unit
}.getOrElse { }
override suspend fun getBans(auth: String): AccountBansModel? = runCatching {
val dto = services.site.get(
auth = auth,
authHeader = auth.toAuthHeader(),
).body()
dto?.myUser?.run {
AccountBansModel(
users = personBlocks.map { it.target.toModel() },
communities = communityBlocks.map { it.community.toModel() },
instances = instanceBlocks.map { it.instance.toModel() },
) = withContext(Dispatchers.IO) {
runCatching {
val formData = value.toDto().copy(auth = auth)
services.user.saveUserSettings(
authHeader = auth.toAuthHeader(),
form = formData,
)
}
}.getOrNull()
Unit
}.getOrElse { }
}
override suspend fun getBans(auth: String): AccountBansModel? = withContext(Dispatchers.IO) {
runCatching {
val dto = services.site.get(
auth = auth,
authHeader = auth.toAuthHeader(),
).body()
dto?.myUser?.run {
AccountBansModel(
users = personBlocks.map { it.target.toModel() },
communities = communityBlocks.map { it.community.toModel() },
instances = instanceBlocks.map { it.instance.toModel() },
)
}
}.getOrNull()
}
}

View File

@ -14,41 +14,48 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toAuthHeader
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toCommentDto
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
internal class DefaultUserRepository(
private val services: ServiceProvider,
private val customServices: ServiceProvider,
) : UserRepository {
override suspend fun getResolved(query: String, auth: String?): UserModel? = kotlin.runCatching {
val response = services.search.resolveObject(
authHeader = auth,
q = query,
).body()
response?.user?.toModel()
}.getOrNull()
override suspend fun getResolved(query: String, auth: String?): UserModel? = withContext(Dispatchers.IO) {
runCatching {
val response = services.search.resolveObject(
authHeader = auth,
q = query,
).body()
response?.user?.toModel()
}.getOrNull()
}
override suspend fun get(
id: Int,
auth: String?,
username: String?,
otherInstance: String?,
): UserModel? = runCatching {
val response = if (otherInstance.isNullOrEmpty()) {
services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
)
} else {
customServices.changeInstance(otherInstance)
customServices.user.getDetails(
username = "$username@$otherInstance",
)
}
val dto = response.body() ?: return@runCatching null
dto.personView.toModel()
}.getOrNull()
): UserModel? = withContext(Dispatchers.IO) {
runCatching {
val response = if (otherInstance.isNullOrEmpty()) {
services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
)
} else {
customServices.changeInstance(otherInstance)
customServices.user.getDetails(
username = "$username@$otherInstance",
)
}
val dto = response.body() ?: return@runCatching null
dto.personView.toModel()
}.getOrNull()
}
override suspend fun getPosts(
id: Int,
@ -58,28 +65,30 @@ internal class DefaultUserRepository(
sort: SortType,
username: String?,
otherInstance: String?,
): List<PostModel>? = runCatching {
val response = if (otherInstance.isNullOrEmpty()) {
services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
page = page,
limit = limit,
sort = sort.toCommentDto(),
)
} else {
customServices.changeInstance(otherInstance)
customServices.user.getDetails(
username = "$username@$otherInstance",
page = page,
limit = limit,
sort = sort.toCommentDto(),
)
}
val dto = response.body() ?: return@runCatching emptyList()
dto.posts.map { it.toModel() }
}.getOrNull()
): List<PostModel>? = withContext(Dispatchers.IO) {
runCatching {
val response = if (otherInstance.isNullOrEmpty()) {
services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
page = page,
limit = limit,
sort = sort.toCommentDto(),
)
} else {
customServices.changeInstance(otherInstance)
customServices.user.getDetails(
username = "$username@$otherInstance",
page = page,
limit = limit,
sort = sort.toCommentDto(),
)
}
val dto = response.body() ?: return@runCatching emptyList()
dto.posts.map { it.toModel() }
}.getOrNull()
}
override suspend fun getSavedPosts(
id: Int,
@ -87,19 +96,21 @@ internal class DefaultUserRepository(
page: Int,
limit: Int,
sort: SortType,
): List<PostModel>? = runCatching {
val response = services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
page = page,
limit = limit,
sort = sort.toCommentDto(),
savedOnly = true,
)
val dto = response.body() ?: return@runCatching emptyList()
dto.posts.map { it.toModel() }
}.getOrNull()
): List<PostModel>? = withContext(Dispatchers.IO) {
runCatching {
val response = services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
page = page,
limit = limit,
sort = sort.toCommentDto(),
savedOnly = true,
)
val dto = response.body() ?: return@runCatching emptyList()
dto.posts.map { it.toModel() }
}.getOrNull()
}
override suspend fun getComments(
id: Int,
@ -109,28 +120,30 @@ internal class DefaultUserRepository(
sort: SortType,
username: String?,
otherInstance: String?,
): List<CommentModel>? = runCatching {
val response = if (otherInstance.isNullOrEmpty()) {
services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
page = page,
limit = limit,
sort = sort.toCommentDto(),
)
} else {
customServices.changeInstance(otherInstance)
customServices.user.getDetails(
username = "$username@$otherInstance",
page = page,
limit = limit,
sort = sort.toCommentDto(),
)
}
val dto = response.body() ?: return@runCatching emptyList()
dto.comments.map { it.toModel() }
}.getOrNull()
): List<CommentModel>? = withContext(Dispatchers.IO) {
runCatching {
val response = if (otherInstance.isNullOrEmpty()) {
services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
page = page,
limit = limit,
sort = sort.toCommentDto(),
)
} else {
customServices.changeInstance(otherInstance)
customServices.user.getDetails(
username = "$username@$otherInstance",
page = page,
limit = limit,
sort = sort.toCommentDto(),
)
}
val dto = response.body() ?: return@runCatching emptyList()
dto.comments.map { it.toModel() }
}.getOrNull()
}
override suspend fun getSavedComments(
id: Int,
@ -138,19 +151,21 @@ internal class DefaultUserRepository(
page: Int,
limit: Int,
sort: SortType,
): List<CommentModel>? = runCatching {
val response = services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
page = page,
limit = limit,
sort = sort.toCommentDto(),
savedOnly = true,
)
val dto = response.body() ?: return@runCatching emptyList()
dto.comments.map { it.toModel() }
}.getOrNull()
): List<CommentModel>? = withContext(Dispatchers.IO) {
runCatching {
val response = services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
page = page,
limit = limit,
sort = sort.toCommentDto(),
savedOnly = true,
)
val dto = response.body() ?: return@runCatching emptyList()
dto.comments.map { it.toModel() }
}.getOrNull()
}
override suspend fun getMentions(
auth: String?,
@ -158,18 +173,20 @@ internal class DefaultUserRepository(
limit: Int,
sort: SortType,
unreadOnly: Boolean,
): List<PersonMentionModel>? = runCatching {
val response = services.user.getMentions(
authHeader = auth.toAuthHeader(),
auth = auth,
limit = limit,
sort = sort.toCommentDto(),
page = page,
unreadOnly = unreadOnly,
)
val dto = response.body() ?: return@runCatching emptyList()
dto.mentions.map { it.toModel() }
}.getOrNull()
): List<PersonMentionModel>? = withContext(Dispatchers.IO) {
runCatching {
val response = services.user.getMentions(
authHeader = auth.toAuthHeader(),
auth = auth,
limit = limit,
sort = sort.toCommentDto(),
page = page,
unreadOnly = unreadOnly,
)
val dto = response.body() ?: return@runCatching emptyList()
dto.mentions.map { it.toModel() }
}.getOrNull()
}
override suspend fun getReplies(
auth: String?,
@ -177,57 +194,63 @@ internal class DefaultUserRepository(
limit: Int,
sort: SortType,
unreadOnly: Boolean,
): List<PersonMentionModel>? = runCatching {
val response = services.user.getReplies(
authHeader = auth.toAuthHeader(),
auth = auth,
limit = limit,
sort = sort.toCommentDto(),
page = page,
unreadOnly = unreadOnly,
)
val dto = response.body() ?: return@runCatching emptyList()
dto.replies.map { it.toModel() }
}.getOrNull()
): List<PersonMentionModel>? = withContext(Dispatchers.IO) {
runCatching {
val response = services.user.getReplies(
authHeader = auth.toAuthHeader(),
auth = auth,
limit = limit,
sort = sort.toCommentDto(),
page = page,
unreadOnly = unreadOnly,
)
val dto = response.body() ?: return@runCatching emptyList()
dto.replies.map { it.toModel() }
}.getOrNull()
}
override suspend fun readAll(
auth: String?,
) {
val data = MarkAllAsReadForm(auth.orEmpty())
services.user.markAllAsRead(
authHeader = auth.toAuthHeader(),
form = data,
)
}
override suspend fun setMentionRead(read: Boolean, mentionId: Int, auth: String?) =
): Unit = withContext(Dispatchers.IO) {
runCatching {
val data = MarkPersonMentionAsReadForm(
mentionId = mentionId,
read = read,
auth = auth.orEmpty(),
)
services.user.markPersonMentionAsRead(
val data = MarkAllAsReadForm(auth.orEmpty())
services.user.markAllAsRead(
authHeader = auth.toAuthHeader(),
form = data,
)
}
}
override suspend fun setMentionRead(read: Boolean, mentionId: Int, auth: String?): Unit =
withContext(Dispatchers.IO) {
runCatching {
val data = MarkPersonMentionAsReadForm(
mentionId = mentionId,
read = read,
auth = auth.orEmpty(),
)
services.user.markPersonMentionAsRead(
authHeader = auth.toAuthHeader(),
form = data,
)
}.getOrElse { }
}
override suspend fun setReplyRead(read: Boolean, replyId: Int, auth: String?): Unit = withContext(Dispatchers.IO) {
runCatching {
val data = MarkCommentAsReadForm(
replyId = replyId,
read = read,
auth = auth.orEmpty(),
)
services.comment.markAsRead(
authHeader = auth.toAuthHeader(),
form = data,
)
Unit
}.getOrElse { }
}
override suspend fun setReplyRead(read: Boolean, replyId: Int, auth: String?) = runCatching {
val data = MarkCommentAsReadForm(
replyId = replyId,
read = read,
auth = auth.orEmpty(),
)
services.comment.markAsRead(
authHeader = auth.toAuthHeader(),
form = data,
)
Unit
}.getOrElse { }
override suspend fun block(id: Int, blocked: Boolean, auth: String?): Result<Unit> =
override suspend fun block(id: Int, blocked: Boolean, auth: String?): Result<Unit> = withContext(Dispatchers.IO) {
runCatching {
val data = BlockPersonForm(
personId = id,
@ -240,18 +263,21 @@ internal class DefaultUserRepository(
)
Unit
}
}
override suspend fun getModeratedCommunities(
auth: String?,
id: Int?,
): List<CommunityModel> = runCatching {
val response = services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
).body()
response?.moderates?.map {
it.community.toModel()
}.orEmpty()
}.getOrElse { emptyList() }
): List<CommunityModel> = withContext(Dispatchers.IO) {
runCatching {
val response = services.user.getDetails(
authHeader = auth.toAuthHeader(),
auth = auth,
personId = id,
).body()
response?.moderates?.map {
it.community.toModel()
}.orEmpty()
}.getOrElse { emptyList() }
}
}

View File

@ -6,8 +6,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationC
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.launch
class BanUserViewModel(
@ -61,7 +59,7 @@ class BanUserViewModel(
val days = currentState.days.toLong().takeIf { newValue }
updateState { it.copy(loading = true) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
val newUser = communityRepository.banUser(

View File

@ -11,8 +11,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepo
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PrivateMessageRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -36,7 +34,7 @@ class InboxChatViewModel(
init {
screenModelScope.launch {
launch(Dispatchers.IO) {
launch {
val auth = identityRepository.authToken.value.orEmpty()
settingsRepository.currentSettings.onEach { settings ->
@ -77,7 +75,7 @@ class InboxChatViewModel(
override fun reduce(intent: InboxChatMviModel.Intent) {
when (intent) {
InboxChatMviModel.Intent.LoadNextPage -> {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
loadNextPage()
}
}
@ -164,7 +162,7 @@ class InboxChatViewModel(
private fun markAsRead(read: Boolean, messageId: Int) {
val auth = identityRepository.authToken.value
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val newMessage = messageRepository.markAsRead(
read = read,
messageId = messageId,
@ -194,7 +192,7 @@ class InboxChatViewModel(
if (bytes.isEmpty()) {
return
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(loading = true) }
val auth = identityRepository.authToken.value.orEmpty()
val url = postRepository.uploadImage(auth, bytes)
@ -221,7 +219,7 @@ class InboxChatViewModel(
val editedMessageId = uiState.value.editedMessageId
val isEditing = editedMessageId != null
if (text.isNotEmpty()) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value
val newMessage = if (isEditing) {
messageRepository.edit(
@ -265,7 +263,7 @@ class InboxChatViewModel(
}
private fun deleteMessage(message: PrivateMessageModel) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value
runCatching {
messageRepository.delete(

View File

@ -17,8 +17,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentR
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.LemmyItemCache
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -154,7 +152,7 @@ class CreateCommentViewModel(
}
updateState { it.copy(loading = true) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
if (postId != null) {
@ -201,7 +199,7 @@ class CreateCommentViewModel(
if (bytes.isEmpty()) {
return
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(loading = true) }
val auth = identityRepository.authToken.value.orEmpty()
val url = postRepository.uploadImage(auth, bytes)

View File

@ -20,8 +20,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.Communit
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.LemmyItemCache
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -145,7 +143,7 @@ class CreatePostViewModel(
val communityId = community.id
val name = community.readableName(preferNicknames)
val auth = identityRepository.authToken.value.orEmpty()
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val communityInfo = name.ifEmpty {
val remoteCommunity = communityRepository.get(auth = auth, id = communityId)
remoteCommunity?.name.orEmpty()
@ -163,7 +161,7 @@ class CreatePostViewModel(
if (bytes.isEmpty()) {
return
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(loading = true) }
val auth = identityRepository.authToken.value.orEmpty()
val url = postRepository.uploadImage(auth, bytes)
@ -180,7 +178,7 @@ class CreatePostViewModel(
if (bytes.isEmpty()) {
return
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(loading = true) }
val auth = identityRepository.authToken.value.orEmpty()
val url = postRepository.uploadImage(auth, bytes)
@ -254,7 +252,7 @@ class CreatePostViewModel(
}
updateState { it.copy(loading = true) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
when {

View File

@ -5,8 +5,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviMode
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.launch
class CreateReportViewModel(
@ -39,7 +37,7 @@ class CreateReportViewModel(
val text = uiState.value.text
updateState { it.copy(loading = true) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
if (postId != null) {

View File

@ -9,8 +9,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.DraftModel
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.DraftType
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.AccountRepository
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.DraftRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.launchIn
@ -62,7 +60,7 @@ class DraftsViewModel(
initial = initial,
)
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val currentState = uiState.value
updateState { it.copy(loading = true) }
val refreshing = currentState.refreshing

View File

@ -122,13 +122,13 @@ class ModalDrawerViewModel(
override fun reduce(intent: ModalDrawerMviModel.Intent) {
when (intent) {
ModalDrawerMviModel.Intent.Refresh -> screenModelScope.launch(Dispatchers.IO) {
ModalDrawerMviModel.Intent.Refresh -> screenModelScope.launch {
refresh()
}
is ModalDrawerMviModel.Intent.SetSearch -> {
updateState { it.copy(searchText = intent.value) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
searchEventChannel.send(Unit)
}
}

View File

@ -10,8 +10,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.GetSortTypesUseCase
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -86,7 +84,7 @@ class InstanceInfoViewModel(
return
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(loading = true) }
val refreshing = currentState.refreshing
val instance = url.replace("https://", "")
@ -128,7 +126,7 @@ class InstanceInfoViewModel(
private fun changeSortType(value: SortType) {
updateState { it.copy(sortType = value) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
emitEffect(InstanceInfoMviModel.Effect.BackToTop)
refresh()
}

View File

@ -12,7 +12,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.identity.usecase.LoginUse
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -114,7 +113,7 @@ class LoginViewModel(
return
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(loading = true) }
val res = communityRepository.getList(

View File

@ -11,7 +11,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.identity.usecase.DeleteAc
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.usecase.LogoutUseCase
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.usecase.SwitchAccountUseCase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -58,13 +57,13 @@ class ManageAccountsViewModel(
is ManageAccountsMviModel.Intent.DeleteAccount -> {
uiState.value.accounts.getOrNull(intent.index)?.also { account ->
if (account.active) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
logout()
deleteAccount(account)
close()
}
} else {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
deleteAccount(account)
updateState {
it.copy(accounts = it.accounts.filter { a -> a.id != account.id })
@ -80,7 +79,7 @@ class ManageAccountsViewModel(
if (account.active) {
return
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
switchAccount(account)
notificationCenter.send(NotificationCenterEvent.ResetHome)
notificationCenter.send(NotificationCenterEvent.ResetExplore)

View File

@ -51,7 +51,7 @@ class ManageBanViewModel(
}
ManageBanMviModel.Intent.Refresh -> {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
refresh()
}
}
@ -76,7 +76,7 @@ class ManageBanViewModel(
}
private fun unbanUser(id: Int) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value.orEmpty()
runCatching {
userRepository.block(
@ -92,7 +92,7 @@ class ManageBanViewModel(
}
private fun unbanCommunity(id: Int) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value.orEmpty()
runCatching {
communityRepository.block(
@ -108,7 +108,7 @@ class ManageBanViewModel(
}
private fun unbanInstance(id: Int) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value.orEmpty()
runCatching {
siteRepository.block(

View File

@ -13,8 +13,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PersonMentionM
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -75,11 +73,11 @@ class InboxMentionsViewModel(
override fun reduce(intent: InboxMentionsMviModel.Intent) {
when (intent) {
InboxMentionsMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
InboxMentionsMviModel.Intent.LoadNextPage -> screenModelScope.launch {
loadNextPage()
}
InboxMentionsMviModel.Intent.Refresh -> screenModelScope.launch(Dispatchers.IO) {
InboxMentionsMviModel.Intent.Refresh -> screenModelScope.launch {
refresh()
}
@ -120,7 +118,7 @@ class InboxMentionsViewModel(
private fun changeUnreadOnly(value: Boolean) {
updateState { it.copy(unreadOnly = value) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
refresh(initial = true)
emitEffect(InboxMentionsMviModel.Effect.BackToTop)
}
@ -181,7 +179,7 @@ class InboxMentionsViewModel(
private fun markAsRead(read: Boolean, mention: PersonMentionModel) {
val auth = identityRepository.authToken.value
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
userRepository.setMentionRead(
read = read,
mentionId = mention.id,
@ -215,7 +213,7 @@ class InboxMentionsViewModel(
score = newComment.score,
)
handleItemUpdate(newMention)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.upVote(
@ -237,7 +235,7 @@ class InboxMentionsViewModel(
score = newComment.score,
)
handleItemUpdate(newMention)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.downVote(
@ -252,7 +250,7 @@ class InboxMentionsViewModel(
}
private fun updateUnreadItems() {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val unreadCount = coordinator.updateUnreadCount()
emitEffect(InboxMentionsMviModel.Effect.UpdateUnreadItems(unreadCount))
}

View File

@ -71,11 +71,11 @@ class InboxMessagesViewModel(
override fun reduce(intent: InboxMessagesMviModel.Intent) {
when (intent) {
InboxMessagesMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
InboxMessagesMviModel.Intent.LoadNextPage -> screenModelScope.launch {
loadNextPage()
}
InboxMessagesMviModel.Intent.Refresh -> screenModelScope.launch(Dispatchers.IO) {
InboxMessagesMviModel.Intent.Refresh -> screenModelScope.launch {
refresh()
}
}
@ -99,7 +99,7 @@ class InboxMessagesViewModel(
return
}
updateState { it.copy(unreadOnly = value) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
refresh(initial = true)
emitEffect(InboxMessagesMviModel.Effect.BackToTop)
}
@ -152,7 +152,7 @@ class InboxMessagesViewModel(
}
private fun updateUnreadItems() {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val unreadCount = coordinator.updateUnreadCount()
emitEffect(InboxMessagesMviModel.Effect.UpdateUnreadItems(unreadCount))
}

View File

@ -9,8 +9,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.Ident
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ListingType
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -54,7 +52,7 @@ class ModdedCommentsViewModel(
override fun reduce(intent: ModdedCommentsMviModel.Intent) {
when (intent) {
ModdedCommentsMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
ModdedCommentsMviModel.Intent.LoadNextPage -> screenModelScope.launch {
loadNextPage()
}
@ -106,7 +104,7 @@ class ModdedCommentsViewModel(
initial = initial,
)
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
loadNextPage()
}
}
@ -180,7 +178,7 @@ class ModdedCommentsViewModel(
voted = newValue,
)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.upVote(
@ -199,7 +197,7 @@ class ModdedCommentsViewModel(
val newValue = comment.myVote >= 0
val newComment = commentRepository.asDownVoted(comment, newValue)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.downVote(
@ -221,7 +219,7 @@ class ModdedCommentsViewModel(
saved = newValue,
)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.save(
@ -237,7 +235,7 @@ class ModdedCommentsViewModel(
}
private fun distinguish(comment: CommentModel) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value.orEmpty()
val newComment = commentRepository.distinguish(
commentId = comment.id,

View File

@ -73,7 +73,7 @@ class ModdedPostsViewModel(
}
ModdedPostsMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
ModdedPostsMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
ModdedPostsMviModel.Intent.LoadNextPage -> screenModelScope.launch {
loadNextPage()
}
@ -118,7 +118,7 @@ class ModdedPostsViewModel(
initial = initial,
)
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
loadNextPage()
}
}
@ -195,7 +195,7 @@ class ModdedPostsViewModel(
voted = newValue,
)
handlePostUpdate(newPost)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.upVote(
@ -220,7 +220,7 @@ class ModdedPostsViewModel(
downVoted = newValue,
)
handlePostUpdate(newPost)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.downVote(

View File

@ -6,8 +6,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviMode
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.SettingsRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.ModlogRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -48,7 +46,7 @@ class ModlogViewModel(
override fun reduce(intent: ModlogMviModel.Intent) {
when (intent) {
ModlogMviModel.Intent.Refresh -> refresh()
ModlogMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
ModlogMviModel.Intent.LoadNextPage -> screenModelScope.launch {
loadNextPage()
}
}
@ -63,7 +61,7 @@ class ModlogViewModel(
initial = initial,
)
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
loadNextPage()
}
}
@ -75,7 +73,7 @@ class ModlogViewModel(
return
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(loading = true) }
val auth = identityRepository.authToken.value.orEmpty()
val refreshing = currentState.refreshing

View File

@ -122,11 +122,11 @@ class ProfileLoggedViewModel(
is ProfileLoggedMviModel.Intent.ChangeSection -> changeSection(intent.section)
is ProfileLoggedMviModel.Intent.DeleteComment -> deleteComment(intent.id)
is ProfileLoggedMviModel.Intent.DeletePost -> deletePost(intent.id)
ProfileLoggedMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
ProfileLoggedMviModel.Intent.LoadNextPage -> screenModelScope.launch {
loadNextPage()
}
ProfileLoggedMviModel.Intent.Refresh -> screenModelScope.launch(Dispatchers.IO) {
ProfileLoggedMviModel.Intent.Refresh -> screenModelScope.launch {
refresh()
}
@ -353,7 +353,7 @@ class ProfileLoggedViewModel(
voted = newVote,
)
handlePostUpdate(newPost)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.upVote(
@ -375,7 +375,7 @@ class ProfileLoggedViewModel(
downVoted = newValue,
)
handlePostUpdate(newPost)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.downVote(
@ -397,7 +397,7 @@ class ProfileLoggedViewModel(
saved = newValue,
)
handlePostUpdate(newPost)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.save(
@ -419,7 +419,7 @@ class ProfileLoggedViewModel(
voted = newValue,
)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.upVote(
@ -438,7 +438,7 @@ class ProfileLoggedViewModel(
val newValue = comment.myVote >= 0
val newComment = commentRepository.asDownVoted(comment, newValue)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.downVote(
@ -460,7 +460,7 @@ class ProfileLoggedViewModel(
saved = newValue,
)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.save(

View File

@ -24,7 +24,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepo
import com.github.diegoberaldin.raccoonforlemmy.unit.postdetail.utils.populateLoadMoreComments
import com.github.diegoberaldin.raccoonforlemmy.unit.postdetail.utils.sortToNestedOrder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -232,13 +231,13 @@ class PostDetailViewModel(
override fun reduce(intent: PostDetailMviModel.Intent) {
when (intent) {
PostDetailMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
PostDetailMviModel.Intent.LoadNextPage -> screenModelScope.launch {
if (!uiState.value.initial) {
loadNextPage()
}
}
PostDetailMviModel.Intent.Refresh -> screenModelScope.launch(Dispatchers.IO) {
PostDetailMviModel.Intent.Refresh -> screenModelScope.launch {
refresh()
}
@ -326,7 +325,7 @@ class PostDetailViewModel(
}
private fun refreshPost() {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value
val updatedPost = postRepository.get(
id = postId,
@ -416,7 +415,7 @@ class PostDetailViewModel(
return
}
updateState { it.copy(sortType = value) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
emitEffect(PostDetailMviModel.Effect.BackToTop)
refresh()
}
@ -429,7 +428,7 @@ class PostDetailViewModel(
}
private fun loadMoreComments(parentId: Int, loadUntilHighlight: Boolean = false) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val currentState = uiState.value
val auth = identityRepository.authToken.value
val sort = currentState.sortType
@ -482,7 +481,7 @@ class PostDetailViewModel(
voted = newValue,
)
updateState { it.copy(post = newPost) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.upVote(
@ -511,7 +510,7 @@ class PostDetailViewModel(
updateState {
it.copy(post = newPost)
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.downVote(
@ -536,7 +535,7 @@ class PostDetailViewModel(
saved = newValue,
)
updateState { it.copy(post = newPost) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.save(
@ -575,7 +574,7 @@ class PostDetailViewModel(
voted = newValue,
)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.upVote(
@ -597,7 +596,7 @@ class PostDetailViewModel(
val newValue = comment.myVote >= 0
val newComment = commentRepository.asDownVoted(comment, newValue)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.downVote(
@ -622,7 +621,7 @@ class PostDetailViewModel(
saved = newValue,
)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.save(
@ -641,7 +640,7 @@ class PostDetailViewModel(
}
private fun deleteComment(id: Int) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.delete(id, auth)
handleCommentDelete(id)
@ -654,7 +653,7 @@ class PostDetailViewModel(
}
private fun deletePost() {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.delete(id = postId, auth = auth)
notificationCenter.send(
@ -697,7 +696,7 @@ class PostDetailViewModel(
}
private fun feature(post: PostModel) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value.orEmpty()
val newPost = postRepository.featureInCommunity(
postId = post.id,
@ -711,7 +710,7 @@ class PostDetailViewModel(
}
private fun lock(post: PostModel) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value.orEmpty()
val newPost = postRepository.lock(
postId = post.id,
@ -725,7 +724,7 @@ class PostDetailViewModel(
}
private fun distinguish(comment: CommentModel) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val auth = identityRepository.authToken.value.orEmpty()
val newComment = commentRepository.distinguish(
commentId = comment.id,
@ -739,7 +738,7 @@ class PostDetailViewModel(
}
private fun toggleModeratorStatus(userId: Int) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val isModerator = uiState.value.moderators.containsId(userId)
val auth = identityRepository.authToken.value.orEmpty()
val post = uiState.value.post

View File

@ -158,7 +158,7 @@ class PostListViewModel(
sortType = settings.defaultPostSortType.toSortType(),
)
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
refresh()
emitEffect(PostListMviModel.Effect.BackToTop)
}
@ -171,11 +171,11 @@ class PostListViewModel(
override fun reduce(intent: PostListMviModel.Intent) {
when (intent) {
PostListMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
PostListMviModel.Intent.LoadNextPage -> screenModelScope.launch {
loadNextPage()
}
PostListMviModel.Intent.Refresh -> screenModelScope.launch(Dispatchers.IO) {
PostListMviModel.Intent.Refresh -> screenModelScope.launch {
refresh()
}
@ -335,7 +335,7 @@ class PostListViewModel(
return
}
updateState { it.copy(sortType = value) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
emitEffect(PostListMviModel.Effect.BackToTop)
refresh()
}

View File

@ -7,8 +7,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationC
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.launch
class RemoveViewModel(
@ -42,7 +40,7 @@ class RemoveViewModel(
val text = uiState.value.text
updateState { it.copy(loading = true) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
if (postId != null) {

View File

@ -14,8 +14,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -78,11 +76,11 @@ class InboxRepliesViewModel(
override fun reduce(intent: InboxRepliesMviModel.Intent) {
when (intent) {
InboxRepliesMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
InboxRepliesMviModel.Intent.LoadNextPage -> screenModelScope.launch {
loadNextPage()
}
InboxRepliesMviModel.Intent.Refresh -> screenModelScope.launch(Dispatchers.IO) {
InboxRepliesMviModel.Intent.Refresh -> screenModelScope.launch {
refresh()
}
@ -127,7 +125,7 @@ class InboxRepliesViewModel(
private fun changeUnreadOnly(value: Boolean) {
updateState { it.copy(unreadOnly = value) }
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
refresh(initial = true)
emitEffect(InboxRepliesMviModel.Effect.BackToTop)
}
@ -188,7 +186,7 @@ class InboxRepliesViewModel(
private fun markAsRead(read: Boolean, reply: PersonMentionModel) {
val auth = identityRepository.authToken.value
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
userRepository.setReplyRead(
read = read,
replyId = reply.id,
@ -218,7 +216,7 @@ class InboxRepliesViewModel(
voted = newValue,
)
handleItemUpdate(newMention)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.upVote(
@ -239,7 +237,7 @@ class InboxRepliesViewModel(
downVoted = newValue
)
handleItemUpdate(newMention)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.downVote(

View File

@ -12,8 +12,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentReportM
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostReportModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.launchIn
@ -66,7 +64,7 @@ class ReportListViewModel(
is ReportListMviModel.Intent.ChangeSection -> changeSection(intent.value)
is ReportListMviModel.Intent.ChangeUnresolvedOnly -> changeUnresolvedOnly(intent.value)
ReportListMviModel.Intent.Refresh -> refresh()
ReportListMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
ReportListMviModel.Intent.LoadNextPage -> screenModelScope.launch {
loadNextPage()
}
@ -108,7 +106,7 @@ class ReportListViewModel(
initial = initial,
)
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
loadNextPage()
}
}
@ -197,7 +195,7 @@ class ReportListViewModel(
}
private fun resolve(report: PostReportModel) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(asyncInProgress = true) }
val auth = identityRepository.authToken.value.orEmpty()
val newReport = postRepository.resolveReport(
@ -217,7 +215,7 @@ class ReportListViewModel(
}
private fun resolve(report: CommentReportModel) {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(asyncInProgress = true) }
val auth = identityRepository.authToken.value.orEmpty()
val newReport = commentRepository.resolveReport(

View File

@ -168,7 +168,7 @@ class SavedItemsViewModel(
return
}
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(loading = true) }
val auth = identityRepository.authToken.value
val user = siteRepository.getCurrentUser(auth.orEmpty()) ?: return@launch
@ -280,7 +280,7 @@ class SavedItemsViewModel(
voted = newValue,
)
handlePostUpdate(newPost)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.upVote(

View File

@ -158,11 +158,11 @@ class UserDetailViewModel(
}
UserDetailMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
UserDetailMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) {
UserDetailMviModel.Intent.LoadNextPage -> screenModelScope.launch {
loadNextPage()
}
UserDetailMviModel.Intent.Refresh -> screenModelScope.launch(Dispatchers.IO) {
UserDetailMviModel.Intent.Refresh -> screenModelScope.launch {
refresh()
}
@ -230,7 +230,7 @@ class UserDetailViewModel(
}
private fun updateAvailableSortTypes() {
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
val sortTypes = if (uiState.value.section == UserDetailSection.Posts) {
getSortTypesUseCase.getTypesForPosts(otherInstance = otherInstance)
} else {
@ -382,7 +382,7 @@ class UserDetailViewModel(
voted = newVote,
)
handlePostUpdate(newPost)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.upVote(
@ -404,7 +404,7 @@ class UserDetailViewModel(
downVoted = newValue,
)
handlePostUpdate(newPost)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.downVote(
@ -426,7 +426,7 @@ class UserDetailViewModel(
saved = newValue,
)
handlePostUpdate(newPost)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
postRepository.save(
@ -448,7 +448,7 @@ class UserDetailViewModel(
voted = newValue,
)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.upVote(
@ -467,7 +467,7 @@ class UserDetailViewModel(
val newValue = comment.myVote >= 0
val newComment = commentRepository.asDownVoted(comment, newValue)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.downVote(
@ -489,7 +489,7 @@ class UserDetailViewModel(
saved = newValue,
)
handleCommentUpdate(newComment)
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
try {
val auth = identityRepository.authToken.value.orEmpty()
commentRepository.save(

View File

@ -12,6 +12,7 @@ import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class ZoomableImageViewModel(
private val settingsRepository: SettingsRepository,
@ -47,7 +48,7 @@ class ZoomableImageViewModel(
private fun downloadAndSave(url: String, folder: String) {
val imageSourcePath = settingsRepository.currentSettings.value.imageSourcePath
screenModelScope.launch(Dispatchers.IO) {
screenModelScope.launch {
updateState { it.copy(loading = true) }
try {
val bytes = galleryHelper.download(url)
@ -55,11 +56,13 @@ class ZoomableImageViewModel(
val idx = s.lastIndexOf(".").takeIf { it >= 0 } ?: s.length
s.substring(idx).takeIf { it.isNotEmpty() } ?: ".jpeg"
}
galleryHelper.saveToGallery(
bytes = bytes,
name = "${epochMillis()}$extension",
additionalPathSegment = folder.takeIf { imageSourcePath },
)
withContext(Dispatchers.IO) {
galleryHelper.saveToGallery(
bytes = bytes,
name = "${epochMillis()}$extension",
additionalPathSegment = folder.takeIf { imageSourcePath },
)
}
emitEffect(ZoomableImageMviModel.Effect.ShareSuccess)
} catch (e: Throwable) {
e.printStackTrace()