mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-03 10:57:41 +01:00
feat: upgrade to lemmy 0.19 (#59)
* chore: add auth headers to all network calls * chore: add support to scaled sort * chore: support for cursor based pagination * chore: relax required fields * feat: add block instance
This commit is contained in:
parent
905916e56f
commit
808f521e20
@ -0,0 +1,10 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.api.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class BlockSiteForm(
|
||||
@SerialName("instance_id") val instanceId: InstanceId,
|
||||
@SerialName("block") val block: Boolean,
|
||||
)
|
@ -15,5 +15,5 @@ data class CommunityAggregates(
|
||||
@SerialName("users_active_week") val usersActiveWeek: Int,
|
||||
@SerialName("users_active_month") val usersActiveMonth: Int,
|
||||
@SerialName("users_active_half_year") val usersActiveHalfYear: Int,
|
||||
@SerialName("hot_rank") val hotRank: Int,
|
||||
@SerialName("hot_rank") val hotRank: Int? = null,
|
||||
)
|
||||
|
@ -6,4 +6,5 @@ import kotlinx.serialization.Serializable
|
||||
@Serializable
|
||||
data class GetPostsResponse(
|
||||
@SerialName("posts") val posts: List<PostView>,
|
||||
@SerialName("next_page") val nextPage: String? = null,
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ data class Person(
|
||||
@SerialName("banner") val banner: String? = null,
|
||||
@SerialName("deleted") val deleted: Boolean,
|
||||
@SerialName("matrix_user_id") val matrixUserId: String? = null,
|
||||
@SerialName("admin") val admin: Boolean,
|
||||
@SerialName("admin") val admin: Boolean? = null,
|
||||
@SerialName("bot_account") val botAccount: Boolean,
|
||||
@SerialName("ban_expires") val banExpires: String? = null,
|
||||
@SerialName("instance_id") val instanceId: InstanceId,
|
||||
|
@ -12,10 +12,10 @@ data class PostAggregates(
|
||||
@SerialName("upvotes") val upvotes: Int,
|
||||
@SerialName("downvotes") val downvotes: Int,
|
||||
@SerialName("published") val published: String,
|
||||
@SerialName("newest_comment_time_necro") val newestCommentTimeNecro: String,
|
||||
@SerialName("newest_comment_time") val newestCommentTime: String,
|
||||
@SerialName("featured_community") val featuredCommunity: Boolean,
|
||||
@SerialName("featured_local") val featuredLocal: Boolean,
|
||||
@SerialName("hot_rank") val hotRank: Int,
|
||||
@SerialName("hot_rank_active") val hotRankActive: Int,
|
||||
@SerialName("newest_comment_time_necro") val newestCommentTimeNecro: String? = null,
|
||||
@SerialName("newest_comment_time") val newestCommentTime: String? = null,
|
||||
@SerialName("featured_community") val featuredCommunity: Boolean? = null,
|
||||
@SerialName("featured_local") val featuredLocal: Boolean? = null,
|
||||
@SerialName("hot_rank") val hotRank: Int? = null,
|
||||
@SerialName("hot_rank_active") val hotRankActive: Int? = null,
|
||||
)
|
||||
|
@ -59,4 +59,7 @@ enum class SortType {
|
||||
|
||||
@SerialName("Controversial")
|
||||
Controversial,
|
||||
|
||||
@SerialName("Scaled")
|
||||
Scaled,
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.SaveCommentForm
|
||||
import de.jensklingenberg.ktorfit.Response
|
||||
import de.jensklingenberg.ktorfit.http.Body
|
||||
import de.jensklingenberg.ktorfit.http.GET
|
||||
import de.jensklingenberg.ktorfit.http.Header
|
||||
import de.jensklingenberg.ktorfit.http.Headers
|
||||
import de.jensklingenberg.ktorfit.http.POST
|
||||
import de.jensklingenberg.ktorfit.http.PUT
|
||||
@ -21,6 +22,7 @@ import de.jensklingenberg.ktorfit.http.Query
|
||||
interface CommentService {
|
||||
@GET("comment/list")
|
||||
suspend fun getAll(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("auth") auth: String? = null,
|
||||
@Query("limit") limit: Int? = null,
|
||||
@Query("sort") sort: CommentSortType? = null,
|
||||
@ -36,27 +38,43 @@ interface CommentService {
|
||||
|
||||
@GET("comment")
|
||||
suspend fun getBy(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("id") id: Int,
|
||||
@Query("auth") auth: String? = null,
|
||||
): Response<GetCommentResponse>
|
||||
|
||||
@PUT("comment/save")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun save(@Body form: SaveCommentForm): Response<CommentResponse>
|
||||
suspend fun save(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: SaveCommentForm,
|
||||
): Response<CommentResponse>
|
||||
|
||||
@POST("comment/like")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun like(@Body form: CreateCommentLikeForm): Response<CommentResponse>
|
||||
suspend fun like(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: CreateCommentLikeForm,
|
||||
): Response<CommentResponse>
|
||||
|
||||
@POST("comment")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun create(@Body form: CreateCommentForm): Response<CommentResponse>
|
||||
suspend fun create(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: CreateCommentForm,
|
||||
): Response<CommentResponse>
|
||||
|
||||
@PUT("comment")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun edit(@Body form: EditCommentForm): Response<CommentResponse>
|
||||
suspend fun edit(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: EditCommentForm,
|
||||
): Response<CommentResponse>
|
||||
|
||||
@POST("comment/delete")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun delete(@Body form: DeleteCommentForm): Response<CommentResponse>
|
||||
suspend fun delete(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: DeleteCommentForm,
|
||||
): Response<CommentResponse>
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.SortType
|
||||
import de.jensklingenberg.ktorfit.Response
|
||||
import de.jensklingenberg.ktorfit.http.Body
|
||||
import de.jensklingenberg.ktorfit.http.GET
|
||||
import de.jensklingenberg.ktorfit.http.Header
|
||||
import de.jensklingenberg.ktorfit.http.Headers
|
||||
import de.jensklingenberg.ktorfit.http.POST
|
||||
import de.jensklingenberg.ktorfit.http.Query
|
||||
@ -18,6 +19,7 @@ interface CommunityService {
|
||||
|
||||
@GET("community")
|
||||
suspend fun get(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("auth") auth: String? = null,
|
||||
@Query("id") id: Int? = null,
|
||||
@Query("name") name: String? = null,
|
||||
@ -25,6 +27,7 @@ interface CommunityService {
|
||||
|
||||
@GET("community/list")
|
||||
suspend fun getAll(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("auth") auth: String? = null,
|
||||
@Query("page") page: Int? = null,
|
||||
@Query("limit") limit: Int? = null,
|
||||
@ -34,9 +37,15 @@ interface CommunityService {
|
||||
|
||||
@POST("community/follow")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun follow(@Body form: FollowCommunityForm): Response<CommunityResponse>
|
||||
suspend fun follow(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: FollowCommunityForm,
|
||||
): Response<CommunityResponse>
|
||||
|
||||
@POST("community/block")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun block(@Body form: BlockCommunityForm): Response<BlockCommunityResponse>
|
||||
suspend fun block(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: BlockCommunityForm,
|
||||
): Response<BlockCommunityResponse>
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import de.jensklingenberg.ktorfit.http.Body
|
||||
import de.jensklingenberg.ktorfit.http.GET
|
||||
import de.jensklingenberg.ktorfit.http.Header
|
||||
import de.jensklingenberg.ktorfit.http.Headers
|
||||
import de.jensklingenberg.ktorfit.http.Multipart
|
||||
import de.jensklingenberg.ktorfit.http.POST
|
||||
import de.jensklingenberg.ktorfit.http.PUT
|
||||
import de.jensklingenberg.ktorfit.http.Query
|
||||
@ -27,10 +26,12 @@ interface PostService {
|
||||
|
||||
@GET("post/list")
|
||||
suspend fun getAll(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("auth") auth: String? = null,
|
||||
@Query("limit") limit: Int? = null,
|
||||
@Query("sort") sort: SortType? = null,
|
||||
@Query("page") page: Int? = null,
|
||||
@Query("page_cursor") pageCursor: String? = null,
|
||||
@Query("type_") type: ListingType? = null,
|
||||
@Query("community_id") communityId: Int? = null,
|
||||
@Query("community_name") communityName: String? = null,
|
||||
@ -39,6 +40,7 @@ interface PostService {
|
||||
|
||||
@GET("post")
|
||||
suspend fun get(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("auth") auth: String? = null,
|
||||
@Query("id") id: Int? = null,
|
||||
@Query("comment_id") commentId: Int? = null,
|
||||
@ -46,28 +48,44 @@ interface PostService {
|
||||
|
||||
@PUT("post/save")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun save(@Body form: SavePostForm): Response<PostResponse>
|
||||
suspend fun save(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: SavePostForm,
|
||||
): Response<PostResponse>
|
||||
|
||||
@POST("post/like")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun like(@Body form: CreatePostLikeForm): Response<PostResponse>
|
||||
suspend fun like(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: CreatePostLikeForm,
|
||||
): Response<PostResponse>
|
||||
|
||||
@POST("post")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun create(@Body form: CreatePostForm): Response<PostResponse>
|
||||
suspend fun create(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: CreatePostForm,
|
||||
): Response<PostResponse>
|
||||
|
||||
@PUT("post")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun edit(@Body form: EditPostForm): Response<PostResponse>
|
||||
suspend fun edit(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: EditPostForm,
|
||||
): Response<PostResponse>
|
||||
|
||||
@POST("post/delete")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun delete(@Body form: DeletePostForm): Response<PostResponse>
|
||||
suspend fun delete(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: DeletePostForm,
|
||||
): Response<PostResponse>
|
||||
|
||||
@POST
|
||||
suspend fun uploadImage(
|
||||
@Url url: String,
|
||||
@Header("Cookie") token: String,
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body content: MultiPartFormDataContent,
|
||||
): Response<PictrsImages>
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.PrivateMessagesResp
|
||||
import de.jensklingenberg.ktorfit.Response
|
||||
import de.jensklingenberg.ktorfit.http.Body
|
||||
import de.jensklingenberg.ktorfit.http.GET
|
||||
import de.jensklingenberg.ktorfit.http.Header
|
||||
import de.jensklingenberg.ktorfit.http.Headers
|
||||
import de.jensklingenberg.ktorfit.http.POST
|
||||
import de.jensklingenberg.ktorfit.http.Query
|
||||
@ -14,6 +15,7 @@ import de.jensklingenberg.ktorfit.http.Query
|
||||
interface PrivateMessageService {
|
||||
@GET("private_message/list")
|
||||
suspend fun getPrivateMessages(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("auth") auth: String? = null,
|
||||
@Query("page") page: Int? = null,
|
||||
@Query("limit") limit: Int? = null,
|
||||
@ -22,9 +24,15 @@ interface PrivateMessageService {
|
||||
|
||||
@POST("private_message")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun createPrivateMessage(@Body form: CreatePrivateMessageForm): Response<PrivateMessageResponse>
|
||||
suspend fun createPrivateMessage(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: CreatePrivateMessageForm,
|
||||
): Response<PrivateMessageResponse>
|
||||
|
||||
@POST("private_message/mark_as_read")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun markPrivateMessageAsRead(@Body form: MarkPrivateMessageAsReadForm): Response<PrivateMessageResponse>
|
||||
suspend fun markPrivateMessageAsRead(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: MarkPrivateMessageAsReadForm,
|
||||
): Response<PrivateMessageResponse>
|
||||
}
|
||||
|
@ -6,11 +6,13 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.SearchType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.SortType
|
||||
import de.jensklingenberg.ktorfit.Response
|
||||
import de.jensklingenberg.ktorfit.http.GET
|
||||
import de.jensklingenberg.ktorfit.http.Header
|
||||
import de.jensklingenberg.ktorfit.http.Query
|
||||
|
||||
interface SearchService {
|
||||
@GET("search")
|
||||
suspend fun search(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("q") q: String,
|
||||
@Query("community_id") communityId: Int? = null,
|
||||
@Query("community_name") communityName: String? = null,
|
||||
|
@ -1,19 +1,33 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.api.service
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.BlockSiteForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.GetSiteMetadataResponse
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.GetSiteResponse
|
||||
import de.jensklingenberg.ktorfit.Response
|
||||
import de.jensklingenberg.ktorfit.http.Body
|
||||
import de.jensklingenberg.ktorfit.http.GET
|
||||
import de.jensklingenberg.ktorfit.http.Header
|
||||
import de.jensklingenberg.ktorfit.http.Headers
|
||||
import de.jensklingenberg.ktorfit.http.POST
|
||||
import de.jensklingenberg.ktorfit.http.Query
|
||||
|
||||
interface SiteService {
|
||||
@GET("site")
|
||||
suspend fun get(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("auth") auth: String? = null,
|
||||
): Response<GetSiteResponse>
|
||||
|
||||
@POST("site/block")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun block(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: BlockSiteForm,
|
||||
): Response<GetSiteResponse>
|
||||
|
||||
@GET("post/site_metadata")
|
||||
suspend fun getSiteMetadata(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("url")
|
||||
url: String,
|
||||
): Response<GetSiteMetadataResponse>
|
||||
|
@ -14,6 +14,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.PersonMentionRespon
|
||||
import de.jensklingenberg.ktorfit.Response
|
||||
import de.jensklingenberg.ktorfit.http.Body
|
||||
import de.jensklingenberg.ktorfit.http.GET
|
||||
import de.jensklingenberg.ktorfit.http.Header
|
||||
import de.jensklingenberg.ktorfit.http.Headers
|
||||
import de.jensklingenberg.ktorfit.http.POST
|
||||
import de.jensklingenberg.ktorfit.http.Query
|
||||
@ -22,6 +23,7 @@ interface UserService {
|
||||
|
||||
@GET("user")
|
||||
suspend fun getDetails(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("auth") auth: String? = null,
|
||||
@Query("community_id") communityId: Int? = null,
|
||||
@Query("person_id") personId: Int? = null,
|
||||
@ -34,6 +36,7 @@ interface UserService {
|
||||
|
||||
@GET("user/mention")
|
||||
suspend fun getMentions(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("auth") auth: String? = null,
|
||||
@Query("page") page: Int? = null,
|
||||
@Query("limit") limit: Int? = null,
|
||||
@ -43,6 +46,7 @@ interface UserService {
|
||||
|
||||
@GET("user/replies")
|
||||
suspend fun getReplies(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Query("auth") auth: String? = null,
|
||||
@Query("page") page: Int? = null,
|
||||
@Query("limit") limit: Int? = null,
|
||||
@ -52,17 +56,29 @@ interface UserService {
|
||||
|
||||
@POST("user/mark_all_as_read")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun markAllAsRead(@Body form: MarkAllAsReadForm): Response<GetRepliesResponse>
|
||||
suspend fun markAllAsRead(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: MarkAllAsReadForm,
|
||||
): Response<GetRepliesResponse>
|
||||
|
||||
@POST("user/mention/mark_as_read")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun markPersonMentionAsRead(@Body form: MarkPersonMentionAsReadForm): Response<PersonMentionResponse>
|
||||
suspend fun markPersonMentionAsRead(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: MarkPersonMentionAsReadForm,
|
||||
): Response<PersonMentionResponse>
|
||||
|
||||
@POST("comment/mark_as_read")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun markCommentReplyAsRead(@Body form: MarkCommentReplyAsReadForm): Response<CommentReplyResponse>
|
||||
suspend fun markCommentReplyAsRead(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: MarkCommentReplyAsReadForm,
|
||||
): Response<CommentReplyResponse>
|
||||
|
||||
@POST("user/block")
|
||||
@Headers("Content-Type: application/json")
|
||||
suspend fun blockPerson(@Body form: BlockPersonForm): Response<BlockPersonResponse>
|
||||
suspend fun block(
|
||||
@Header("Authorization") authHeader: String? = null,
|
||||
@Body form: BlockPersonForm,
|
||||
): Response<BlockPersonResponse>
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ interface CommunityDetailMviModel :
|
||||
data class DeletePost(val id: Int) : Intent
|
||||
data class SharePost(val index: Int) : Intent
|
||||
data object Block : Intent
|
||||
data object BlockInstance : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
|
@ -285,15 +285,15 @@ class CommunityDetailScreen(
|
||||
stringResource(MR.strings.community_detail_info),
|
||||
stringResource(MR.strings.community_detail_instance_info),
|
||||
stringResource(MR.strings.community_detail_block),
|
||||
stringResource(MR.strings.community_detail_block_instance),
|
||||
),
|
||||
onOpenImage = { url ->
|
||||
navigator?.push(ZoomableImageScreen(url))
|
||||
},
|
||||
onOptionSelected = { optionIdx ->
|
||||
when (optionIdx) {
|
||||
2 -> {
|
||||
model.reduce(CommunityDetailMviModel.Intent.Block)
|
||||
}
|
||||
3 -> model.reduce(CommunityDetailMviModel.Intent.BlockInstance)
|
||||
2 -> model.reduce(CommunityDetailMviModel.Intent.Block)
|
||||
|
||||
1 -> {
|
||||
navigator?.push(
|
||||
|
@ -37,6 +37,7 @@ class CommunityDetailViewModel(
|
||||
CommunityDetailMviModel {
|
||||
|
||||
private var currentPage: Int = 1
|
||||
private var pageCursor: String? = null
|
||||
|
||||
override fun onStarted() {
|
||||
mvi.onStarted()
|
||||
@ -107,11 +108,13 @@ class CommunityDetailViewModel(
|
||||
)
|
||||
|
||||
CommunityDetailMviModel.Intent.Block -> blockCommunity()
|
||||
CommunityDetailMviModel.Intent.BlockInstance -> blockInstance()
|
||||
}
|
||||
}
|
||||
|
||||
private fun refresh() {
|
||||
currentPage = 1
|
||||
pageCursor = null
|
||||
mvi.updateState { it.copy(canFetchMore = true, refreshing = true) }
|
||||
val auth = identityRepository.authToken.value
|
||||
mvi.scope?.launch(Dispatchers.IO) {
|
||||
@ -153,11 +156,12 @@ class CommunityDetailViewModel(
|
||||
val refreshing = currentState.refreshing
|
||||
val sort = currentState.sortType
|
||||
val communityId = currentState.community.id
|
||||
val itemList = if (otherInstance.isNotEmpty()) {
|
||||
val (itemList, nextPage) = if (otherInstance.isNotEmpty()) {
|
||||
postRepository.getAll(
|
||||
instance = otherInstance,
|
||||
communityId = communityId,
|
||||
page = currentPage,
|
||||
pageCursor = pageCursor,
|
||||
sort = sort,
|
||||
)
|
||||
} else {
|
||||
@ -165,12 +169,28 @@ class CommunityDetailViewModel(
|
||||
auth = auth,
|
||||
communityId = communityId,
|
||||
page = currentPage,
|
||||
pageCursor = pageCursor,
|
||||
sort = sort,
|
||||
)
|
||||
}
|
||||
}?.let {
|
||||
if (refreshing) {
|
||||
it
|
||||
} else {
|
||||
// prevents accidental duplication
|
||||
val posts = it.first
|
||||
it.copy(
|
||||
first = posts.filter { p1 ->
|
||||
currentState.posts.none { p2 -> p2.id == p1.id }
|
||||
},
|
||||
)
|
||||
}
|
||||
} ?: (null to null)
|
||||
if (!itemList.isNullOrEmpty()) {
|
||||
currentPage++
|
||||
}
|
||||
if (nextPage != null) {
|
||||
pageCursor = nextPage
|
||||
}
|
||||
mvi.updateState {
|
||||
val newItems = if (refreshing) {
|
||||
itemList.orEmpty()
|
||||
@ -383,4 +403,20 @@ class CommunityDetailViewModel(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun blockInstance() {
|
||||
mvi.updateState { it.copy(asyncInProgress = true) }
|
||||
mvi.scope?.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val instanceId = community.instanceId
|
||||
val auth = identityRepository.authToken.value
|
||||
siteRepository.block(instanceId, true, auth).getOrThrow()
|
||||
mvi.emitEffect(CommunityDetailMviModel.Effect.BlockSuccess)
|
||||
} catch (e: Throwable) {
|
||||
mvi.emitEffect(CommunityDetailMviModel.Effect.BlockError(e.message))
|
||||
} finally {
|
||||
mvi.updateState { it.copy(asyncInProgress = false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ val commonUiModule = module {
|
||||
userRepository = get(),
|
||||
postRepository = get(),
|
||||
commentRepository = get(),
|
||||
siteRepository = get(),
|
||||
themeRepository = get(),
|
||||
settingsRepository = get(),
|
||||
shareHelper = get(),
|
||||
|
@ -35,6 +35,7 @@ class InstanceInfoViewModel(
|
||||
|
||||
val metadata = siteRepository.getMetadata(url)
|
||||
if (metadata != null) {
|
||||
metadata.title
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
title = metadata.title,
|
||||
|
@ -46,6 +46,7 @@ class SortBottomSheet(
|
||||
SortType.MostComments,
|
||||
SortType.Old,
|
||||
SortType.Controversial,
|
||||
SortType.Scaled,
|
||||
SortType.Top.Generic,
|
||||
),
|
||||
private val expandTop: Boolean = false,
|
||||
@ -68,7 +69,6 @@ class SortBottomSheet(
|
||||
SortBottomSheetMain(
|
||||
values = values,
|
||||
expandTop = expandTop,
|
||||
mainKey = key,
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -78,7 +78,6 @@ class SortBottomSheet(
|
||||
internal class SortBottomSheetMain(
|
||||
private val values: List<SortType>,
|
||||
private val expandTop: Boolean = false,
|
||||
private val mainKey: String,
|
||||
) : Screen {
|
||||
@Composable
|
||||
override fun Content() {
|
||||
|
@ -22,11 +22,11 @@ interface UserDetailMviModel :
|
||||
data class SavePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVoteComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVoteComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
|
||||
data class SaveComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data object HapticIndication : Intent
|
||||
data class SharePost(val index: Int) : Intent
|
||||
data object Block : Intent
|
||||
data object BlockInstance : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
|
@ -263,15 +263,17 @@ class UserDetailScreen(
|
||||
UserHeader(
|
||||
user = uiState.user,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
options = listOf(stringResource(MR.strings.community_detail_block)),
|
||||
options = listOf(
|
||||
stringResource(MR.strings.community_detail_block),
|
||||
stringResource(MR.strings.community_detail_block_instance),
|
||||
),
|
||||
onOpenImage = { url ->
|
||||
navigator?.push(ZoomableImageScreen(url))
|
||||
},
|
||||
onOptionSelected = { optionIdx ->
|
||||
when (optionIdx) {
|
||||
else -> {
|
||||
model.reduce(UserDetailMviModel.Intent.Block)
|
||||
}
|
||||
1 -> model.reduce(UserDetailMviModel.Intent.BlockInstance)
|
||||
else -> model.reduce(UserDetailMviModel.Intent.Block)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -17,6 +17,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.shareUrl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toSortType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository
|
||||
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
|
||||
@ -32,6 +33,7 @@ class UserDetailViewModel(
|
||||
private val userRepository: UserRepository,
|
||||
private val postRepository: PostRepository,
|
||||
private val commentRepository: CommentRepository,
|
||||
private val siteRepository: SiteRepository,
|
||||
private val themeRepository: ThemeRepository,
|
||||
private val shareHelper: ShareHelper,
|
||||
private val hapticFeedback: HapticFeedback,
|
||||
@ -129,6 +131,7 @@ class UserDetailViewModel(
|
||||
)
|
||||
|
||||
UserDetailMviModel.Intent.Block -> blockUser()
|
||||
UserDetailMviModel.Intent.BlockInstance -> blockInstance()
|
||||
}
|
||||
}
|
||||
|
||||
@ -557,4 +560,20 @@ class UserDetailViewModel(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun blockInstance() {
|
||||
mvi.updateState { it.copy(asyncInProgress = true) }
|
||||
mvi.scope?.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val instanceId = user.instanceId
|
||||
val auth = identityRepository.authToken.value
|
||||
siteRepository.block(instanceId, true, auth).getOrThrow()
|
||||
mvi.emitEffect(UserDetailMviModel.Effect.BlockSuccess)
|
||||
} catch (e: Throwable) {
|
||||
mvi.emitEffect(UserDetailMviModel.Effect.BlockError(e.message))
|
||||
} finally {
|
||||
mvi.updateState { it.copy(asyncInProgress = false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.utils.JavaSerializable
|
||||
|
||||
data class CommunityModel(
|
||||
val id: Int = 0,
|
||||
val instanceId: Int = 0,
|
||||
val name: String = "",
|
||||
val description: String = "",
|
||||
val title: String = "",
|
||||
|
@ -6,6 +6,7 @@ import androidx.compose.material.icons.filled.Forum
|
||||
import androidx.compose.material.icons.filled.LocalFireDepartment
|
||||
import androidx.compose.material.icons.filled.MarkUnreadChatAlt
|
||||
import androidx.compose.material.icons.filled.MilitaryTech
|
||||
import androidx.compose.material.icons.filled.MonitorWeight
|
||||
import androidx.compose.material.icons.filled.RocketLaunch
|
||||
import androidx.compose.material.icons.filled.Thunderstorm
|
||||
import androidx.compose.material.icons.filled.TrendingUp
|
||||
@ -33,6 +34,7 @@ sealed interface SortType {
|
||||
}
|
||||
|
||||
data object Controversial : SortType
|
||||
data object Scaled : SortType
|
||||
}
|
||||
|
||||
fun SortType.toInt() = when (this) {
|
||||
@ -50,6 +52,7 @@ fun SortType.toInt() = when (this) {
|
||||
SortType.Top.Year -> 12
|
||||
SortType.Old -> 13
|
||||
SortType.Controversial -> 14
|
||||
SortType.Scaled -> 15
|
||||
else -> 0
|
||||
}
|
||||
|
||||
@ -68,6 +71,7 @@ fun Int.toSortType() = when (this) {
|
||||
12 -> SortType.Top.Year
|
||||
13 -> SortType.Old
|
||||
14 -> SortType.Controversial
|
||||
15 -> SortType.Scaled
|
||||
else -> SortType.Active
|
||||
}
|
||||
|
||||
@ -79,6 +83,7 @@ fun SortType.toIcon(): ImageVector = when (this) {
|
||||
SortType.NewComments -> Icons.Default.MarkUnreadChatAlt
|
||||
SortType.Old -> Icons.Default.ElderlyWoman
|
||||
SortType.Controversial -> Icons.Default.Thunderstorm
|
||||
SortType.Scaled -> Icons.Default.MonitorWeight
|
||||
else -> Icons.Default.MilitaryTech
|
||||
}
|
||||
|
||||
@ -98,5 +103,6 @@ fun SortType.toReadableName(): String = when (this) {
|
||||
SortType.Top.Year -> stringResource(MR.strings.home_sort_type_top_year)
|
||||
SortType.Old -> stringResource(MR.strings.home_sort_type_old)
|
||||
SortType.Controversial -> stringResource(MR.strings.home_sort_type_controversial)
|
||||
SortType.Scaled -> stringResource(MR.strings.home_sort_type_scaled)
|
||||
else -> stringResource(MR.strings.home_sort_type_top)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.utils.JavaSerializable
|
||||
|
||||
data class UserModel(
|
||||
val id: Int = 0,
|
||||
val instanceId: Int = 0,
|
||||
val name: String = "",
|
||||
val displayName: String = "",
|
||||
val avatar: String? = null,
|
||||
|
@ -10,6 +10,7 @@ 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.data.PersonMentionModel
|
||||
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.toCommentDto
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toDto
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
|
||||
@ -35,6 +36,7 @@ class CommentRepository(
|
||||
): List<CommentModel>? = runCatching {
|
||||
val response = if (instance.isNullOrEmpty()) {
|
||||
services.comment.getAll(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
postId = postId,
|
||||
page = page,
|
||||
@ -61,10 +63,14 @@ class CommentRepository(
|
||||
suspend fun getBy(id: Int, auth: String?, instance: String? = null): CommentModel? =
|
||||
runCatching {
|
||||
if (instance.isNullOrEmpty()) {
|
||||
services.comment.getBy(id, auth).body()
|
||||
services.comment.getBy(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
id = id,
|
||||
auth = auth,
|
||||
).body()
|
||||
} else {
|
||||
customServices.changeInstance(instance)
|
||||
customServices.comment.getBy(id).body()
|
||||
customServices.comment.getBy(id = id).body()
|
||||
}?.commentView?.toModel()
|
||||
}.getOrNull()
|
||||
|
||||
@ -79,6 +85,7 @@ class CommentRepository(
|
||||
): List<CommentModel>? = runCatching {
|
||||
val response = if (instance.isNullOrEmpty()) {
|
||||
services.comment.getAll(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
parentId = parentId,
|
||||
limit = limit,
|
||||
@ -142,7 +149,7 @@ class CommentRepository(
|
||||
score = if (voted) 1 else 0,
|
||||
auth = auth,
|
||||
)
|
||||
services.comment.like(data)
|
||||
services.comment.like(authHeader = auth.toAuthHeader(), form = data)
|
||||
}
|
||||
|
||||
fun asDownVoted(comment: CommentModel, downVoted: Boolean) = comment.copy(
|
||||
@ -187,7 +194,7 @@ class CommentRepository(
|
||||
score = if (downVoted) -1 else 0,
|
||||
auth = auth,
|
||||
)
|
||||
services.comment.like(data)
|
||||
services.comment.like(authHeader = auth.toAuthHeader(), form = data)
|
||||
}
|
||||
|
||||
fun asSaved(comment: CommentModel, saved: Boolean) = comment.copy(saved = saved)
|
||||
@ -198,7 +205,7 @@ class CommentRepository(
|
||||
save = saved,
|
||||
auth = auth,
|
||||
)
|
||||
services.comment.save(data)
|
||||
services.comment.save(authHeader = auth.toAuthHeader(), form = data)
|
||||
}
|
||||
|
||||
suspend fun create(
|
||||
@ -213,7 +220,7 @@ class CommentRepository(
|
||||
parentId = parentId,
|
||||
auth = auth,
|
||||
)
|
||||
services.comment.create(data)
|
||||
services.comment.create(authHeader = auth.toAuthHeader(), form = data)
|
||||
}
|
||||
|
||||
suspend fun edit(
|
||||
@ -226,7 +233,7 @@ class CommentRepository(
|
||||
commentId = commentId,
|
||||
auth = auth,
|
||||
)
|
||||
services.comment.edit(data)
|
||||
services.comment.edit(authHeader = auth.toAuthHeader(), form = data)
|
||||
}
|
||||
|
||||
suspend fun delete(
|
||||
@ -238,6 +245,6 @@ class CommentRepository(
|
||||
deleted = true,
|
||||
auth = auth
|
||||
)
|
||||
services.comment.delete(data)
|
||||
services.comment.delete(authHeader = auth.toAuthHeader(), form = data)
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ListingType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SearchResultType
|
||||
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
|
||||
|
||||
@ -33,6 +34,7 @@ class CommunityRepository(
|
||||
): List<Any>? = runCatching {
|
||||
if (instance.isNullOrEmpty()) {
|
||||
val response = services.search.search(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
q = query,
|
||||
auth = auth,
|
||||
page = page,
|
||||
@ -61,7 +63,10 @@ class CommunityRepository(
|
||||
suspend fun getSubscribed(
|
||||
auth: String? = null,
|
||||
): List<CommunityModel> = runCatching {
|
||||
val response = services.site.get(auth).body()
|
||||
val response = services.site.get(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
).body()
|
||||
response?.myUser?.follows?.map { it.community.toModel() }.orEmpty()
|
||||
}.getOrElse { emptyList() }
|
||||
|
||||
@ -73,16 +78,14 @@ class CommunityRepository(
|
||||
): 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(
|
||||
auth = auth,
|
||||
name = name,
|
||||
).body()
|
||||
customServices.community.get(name = name).body()
|
||||
}
|
||||
response?.communityView?.toModel()
|
||||
}.getOrNull()
|
||||
@ -96,7 +99,10 @@ class CommunityRepository(
|
||||
communityId = id,
|
||||
follow = true,
|
||||
)
|
||||
val response = services.community.follow(data)
|
||||
val response = services.community.follow(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data
|
||||
)
|
||||
response.body()?.communityView?.toModel()
|
||||
}.getOrNull()
|
||||
|
||||
@ -109,7 +115,10 @@ class CommunityRepository(
|
||||
communityId = id,
|
||||
follow = false,
|
||||
)
|
||||
val response = services.community.follow(data)
|
||||
val response = services.community.follow(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data
|
||||
)
|
||||
response.body()?.communityView?.toModel()
|
||||
}.getOrNull()
|
||||
|
||||
@ -119,7 +128,10 @@ class CommunityRepository(
|
||||
block = blocked,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
services.community.block(data)
|
||||
services.community.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.provider.ServiceProvide
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ListingType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
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
|
||||
@ -28,17 +29,20 @@ class PostRepository(
|
||||
suspend fun getAll(
|
||||
auth: String? = null,
|
||||
page: Int,
|
||||
pageCursor: String? = null,
|
||||
limit: Int = DEFAULT_PAGE_SIZE,
|
||||
type: ListingType = ListingType.Local,
|
||||
sort: SortType = SortType.Active,
|
||||
communityId: Int? = null,
|
||||
instance: String? = null,
|
||||
): List<PostModel>? = runCatching {
|
||||
): Pair<List<PostModel>, String?>? = runCatching {
|
||||
val response = if (instance.isNullOrEmpty()) {
|
||||
services.post.getAll(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
communityId = communityId,
|
||||
page = page,
|
||||
pageCursor = pageCursor,
|
||||
limit = limit,
|
||||
type = type.toDto(),
|
||||
sort = sort.toDto(),
|
||||
@ -48,13 +52,15 @@ class PostRepository(
|
||||
customServices.post.getAll(
|
||||
communityId = communityId,
|
||||
page = page,
|
||||
pageCursor = pageCursor,
|
||||
limit = limit,
|
||||
type = type.toDto(),
|
||||
sort = sort.toDto(),
|
||||
)
|
||||
}
|
||||
val dto = response.body()?.posts ?: emptyList()
|
||||
dto.map { it.toModel() }
|
||||
val body = response.body()
|
||||
val posts = body?.posts?.map { it.toModel() } ?: emptyList()
|
||||
posts to body?.nextPage
|
||||
}.getOrNull()
|
||||
|
||||
suspend fun get(
|
||||
@ -63,7 +69,11 @@ class PostRepository(
|
||||
instance: String? = null,
|
||||
): PostModel? = runCatching {
|
||||
val response = if (instance.isNullOrEmpty()) {
|
||||
services.post.get(auth, id).body()
|
||||
services.post.get(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
id = id,
|
||||
).body()
|
||||
} else {
|
||||
customServices.changeInstance(instance)
|
||||
customServices.post.get(id = id).body()
|
||||
@ -98,7 +108,10 @@ class PostRepository(
|
||||
score = if (voted) 1 else 0,
|
||||
auth = auth,
|
||||
)
|
||||
services.post.like(data)
|
||||
services.post.like(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
fun asDownVoted(post: PostModel, downVoted: Boolean) = post.copy(
|
||||
@ -125,7 +138,10 @@ class PostRepository(
|
||||
score = if (downVoted) -1 else 0,
|
||||
auth = auth,
|
||||
)
|
||||
services.post.like(data)
|
||||
services.post.like(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
fun asSaved(post: PostModel, saved: Boolean): PostModel = post.copy(saved = saved)
|
||||
@ -136,7 +152,10 @@ class PostRepository(
|
||||
save = saved,
|
||||
auth = auth,
|
||||
)
|
||||
services.post.save(data)
|
||||
services.post.save(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun create(
|
||||
@ -155,7 +174,10 @@ class PostRepository(
|
||||
nsfw = nsfw,
|
||||
auth = auth,
|
||||
)
|
||||
services.post.create(data)
|
||||
services.post.create(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun edit(
|
||||
@ -174,7 +196,10 @@ class PostRepository(
|
||||
nsfw = nsfw,
|
||||
auth = auth,
|
||||
)
|
||||
services.post.edit(data)
|
||||
services.post.edit(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun delete(id: Int, auth: String) {
|
||||
@ -183,7 +208,10 @@ class PostRepository(
|
||||
deleted = true,
|
||||
auth = auth
|
||||
)
|
||||
services.post.delete(data)
|
||||
services.post.delete(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun uploadImage(auth: String, bytes: ByteArray): String? = try {
|
||||
@ -194,7 +222,12 @@ class PostRepository(
|
||||
append(HttpHeaders.ContentDisposition, "filename=image.jpeg")
|
||||
})
|
||||
})
|
||||
val images = services.post.uploadImage(url, "jwt=$auth", multipart).body()
|
||||
val images = services.post.uploadImage(
|
||||
url = url,
|
||||
token = "jwt=$auth",
|
||||
authHeader = auth.toAuthHeader(),
|
||||
content = multipart,
|
||||
).body()
|
||||
"$url/${images?.files?.firstOrNull()?.file}"
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
@ -4,6 +4,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.CreatePrivateMessag
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.MarkPrivateMessageAsReadForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.provider.ServiceProvider
|
||||
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
|
||||
|
||||
class PrivateMessageRepository(
|
||||
@ -16,6 +17,7 @@ class PrivateMessageRepository(
|
||||
unreadOnly: Boolean = true,
|
||||
): List<PrivateMessageModel>? = runCatching {
|
||||
val response = serviceProvider.privateMessages.getPrivateMessages(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
limit = limit,
|
||||
page = page,
|
||||
@ -35,7 +37,10 @@ class PrivateMessageRepository(
|
||||
auth = auth.orEmpty(),
|
||||
recipientId = recipiendId,
|
||||
)
|
||||
serviceProvider.privateMessages.createPrivateMessage(data)
|
||||
serviceProvider.privateMessages.createPrivateMessage(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun markAsRead(
|
||||
@ -48,6 +53,9 @@ class PrivateMessageRepository(
|
||||
auth = auth.orEmpty(),
|
||||
read = read,
|
||||
)
|
||||
serviceProvider.privateMessages.markPrivateMessageAsRead(data)
|
||||
serviceProvider.privateMessages.markPrivateMessageAsRead(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
}
|
@ -1,16 +1,21 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.BlockSiteForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.SiteMetadata
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.provider.ServiceProvider
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.MetadataModel
|
||||
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.toModel
|
||||
|
||||
class SiteRepository(
|
||||
private val serviceProvider: ServiceProvider,
|
||||
) {
|
||||
suspend fun getCurrentUser(auth: String): UserModel? = runCatching {
|
||||
val response = serviceProvider.site.get(auth = auth)
|
||||
val response = serviceProvider.site.get(
|
||||
auth = auth,
|
||||
authHeader = auth.toAuthHeader(),
|
||||
)
|
||||
response.body()?.myUser?.let {
|
||||
val user = it.localUserView.person
|
||||
val counts = it.localUserView.counts
|
||||
@ -18,8 +23,21 @@ class SiteRepository(
|
||||
}
|
||||
}.getOrNull()
|
||||
|
||||
suspend fun block(id: Int, blocked: Boolean, auth: String? = null): Result<Unit> = runCatching {
|
||||
val data = BlockSiteForm(
|
||||
instanceId = id,
|
||||
block = blocked,
|
||||
)
|
||||
serviceProvider.site.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getMetadata(url: String): MetadataModel? = runCatching {
|
||||
val response = serviceProvider.site.getSiteMetadata(url = url)
|
||||
val response = serviceProvider.site.getSiteMetadata(
|
||||
url = url,
|
||||
)
|
||||
response.body()?.metadata?.toModel()
|
||||
}.getOrNull()
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PersonMentionM
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
||||
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.toHost
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
|
||||
@ -25,6 +26,7 @@ class UserRepository(
|
||||
username: String? = null,
|
||||
): UserModel? = runCatching {
|
||||
val response = serviceProvider.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
personId = id,
|
||||
username = username,
|
||||
@ -48,6 +50,7 @@ class UserRepository(
|
||||
): UserModel? = runCatching {
|
||||
customServiceProvider.changeInstance(instance)
|
||||
val response = customServiceProvider.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
username = username,
|
||||
)
|
||||
@ -71,6 +74,7 @@ class UserRepository(
|
||||
sort: SortType = SortType.Active,
|
||||
): List<PostModel>? = runCatching {
|
||||
val response = serviceProvider.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
personId = id,
|
||||
page = page,
|
||||
@ -89,6 +93,7 @@ class UserRepository(
|
||||
sort: SortType = SortType.Active,
|
||||
): List<PostModel>? = runCatching {
|
||||
val response = serviceProvider.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
personId = id,
|
||||
page = page,
|
||||
@ -108,6 +113,7 @@ class UserRepository(
|
||||
sort: SortType = SortType.Active,
|
||||
): List<CommentModel>? = runCatching {
|
||||
val response = serviceProvider.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
personId = id,
|
||||
page = page,
|
||||
@ -126,6 +132,7 @@ class UserRepository(
|
||||
sort: SortType = SortType.Active,
|
||||
): List<CommentModel>? = runCatching {
|
||||
val response = serviceProvider.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
personId = id,
|
||||
page = page,
|
||||
@ -145,6 +152,7 @@ class UserRepository(
|
||||
unreadOnly: Boolean = true,
|
||||
): List<PersonMentionModel>? = runCatching {
|
||||
val response = serviceProvider.user.getMentions(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
limit = limit,
|
||||
sort = sort.toCommentDto(),
|
||||
@ -163,6 +171,7 @@ class UserRepository(
|
||||
unreadOnly: Boolean = true,
|
||||
): List<PersonMentionModel>? = runCatching {
|
||||
val response = serviceProvider.user.getReplies(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
limit = limit,
|
||||
sort = sort.toCommentDto(),
|
||||
@ -177,7 +186,10 @@ class UserRepository(
|
||||
auth: String? = null,
|
||||
) {
|
||||
val data = MarkAllAsReadForm(auth.orEmpty())
|
||||
serviceProvider.user.markAllAsRead(data)
|
||||
serviceProvider.user.markAllAsRead(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun setMentionRead(read: Boolean, mentionId: Int, auth: String? = null) = runCatching {
|
||||
@ -186,7 +198,10 @@ class UserRepository(
|
||||
read = read,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
serviceProvider.user.markPersonMentionAsRead(data)
|
||||
serviceProvider.user.markPersonMentionAsRead(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun setReplyRead(read: Boolean, replyId: Int, auth: String? = null) = runCatching {
|
||||
@ -195,7 +210,10 @@ class UserRepository(
|
||||
read = read,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
serviceProvider.user.markCommentReplyAsRead(data)
|
||||
serviceProvider.user.markCommentReplyAsRead(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun block(id: Int, blocked: Boolean, auth: String? = null): Result<Unit> = runCatching {
|
||||
@ -204,6 +222,9 @@ class UserRepository(
|
||||
block = blocked,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
serviceProvider.user.blockPerson(data)
|
||||
serviceProvider.user.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ internal fun SearchResultType.toDto(): SearchType = when (this) {
|
||||
|
||||
internal fun Person.toModel() = UserModel(
|
||||
id = id,
|
||||
instanceId = instanceId,
|
||||
name = name,
|
||||
displayName = displayName.orEmpty(),
|
||||
avatar = avatar,
|
||||
@ -131,6 +132,7 @@ internal fun CommentView.toModel() = CommentModel(
|
||||
|
||||
internal fun Community.toModel() = CommunityModel(
|
||||
id = id,
|
||||
instanceId = instanceId,
|
||||
name = name,
|
||||
title = title,
|
||||
description = description.orEmpty(),
|
||||
@ -222,6 +224,8 @@ internal fun PrivateMessageView.toModel() = PrivateMessageModel(
|
||||
read = privateMessage.read,
|
||||
)
|
||||
|
||||
internal fun String?.toAuthHeader() = this?.let { "Bearer $it" }
|
||||
|
||||
internal fun String.toHost(): String = this.replace("https://", "").let {
|
||||
val index = it.indexOf("/")
|
||||
if (index < 0) {
|
||||
|
@ -40,6 +40,7 @@ class PostListViewModel(
|
||||
MviModel<PostListMviModel.Intent, PostListMviModel.UiState, PostListMviModel.Effect> by mvi {
|
||||
|
||||
private var currentPage: Int = 1
|
||||
private var pageCursor: String? = null
|
||||
private var firstLoad = true
|
||||
|
||||
init {
|
||||
@ -150,6 +151,7 @@ class PostListViewModel(
|
||||
|
||||
private fun refresh() {
|
||||
currentPage = 1
|
||||
pageCursor = null
|
||||
mvi.updateState { it.copy(canFetchMore = true, refreshing = true) }
|
||||
loadNextPage()
|
||||
}
|
||||
@ -168,9 +170,10 @@ class PostListViewModel(
|
||||
val sort = currentState.sortType ?: SortType.Active
|
||||
val refreshing = currentState.refreshing
|
||||
val includeNsfw = settingsRepository.currentSettings.value.includeNsfw
|
||||
val itemList = postRepository.getAll(
|
||||
val (itemList, nextPage) = postRepository.getAll(
|
||||
auth = auth,
|
||||
page = currentPage,
|
||||
pageCursor = pageCursor,
|
||||
type = type,
|
||||
sort = sort,
|
||||
)?.let {
|
||||
@ -178,14 +181,20 @@ class PostListViewModel(
|
||||
it
|
||||
} else {
|
||||
// prevents accidental duplication
|
||||
it.filter { p1 ->
|
||||
currentState.posts.none { p2 -> p2.id == p1.id }
|
||||
}
|
||||
val posts = it.first
|
||||
it.copy(
|
||||
first = posts.filter { p1 ->
|
||||
currentState.posts.none { p2 -> p2.id == p1.id }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
} ?: (null to null)
|
||||
if (!itemList.isNullOrEmpty()) {
|
||||
currentPage++
|
||||
}
|
||||
if (nextPage != null) {
|
||||
pageCursor = nextPage
|
||||
}
|
||||
mvi.updateState {
|
||||
val newPosts = if (refreshing) {
|
||||
itemList.orEmpty()
|
||||
@ -375,6 +384,7 @@ class PostListViewModel(
|
||||
|
||||
private fun handleLogout() {
|
||||
currentPage = 1
|
||||
pageCursor = null
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
posts = emptyList(),
|
||||
|
@ -10,11 +10,13 @@ internal class CommunityPaginator(
|
||||
private val postRepository: PostRepository,
|
||||
) {
|
||||
private var currentPage: Int = 1
|
||||
private var pageCursor: String? = null
|
||||
var canFetchMore: Boolean = true
|
||||
private set
|
||||
|
||||
fun reset() {
|
||||
currentPage = 1
|
||||
pageCursor = null
|
||||
canFetchMore = true
|
||||
}
|
||||
|
||||
@ -23,20 +25,29 @@ internal class CommunityPaginator(
|
||||
sort: SortType,
|
||||
currentIds: List<Int>,
|
||||
): List<PostModel> {
|
||||
val result = postRepository.getAll(
|
||||
val (result, nextPage) = postRepository.getAll(
|
||||
auth = auth,
|
||||
page = currentPage,
|
||||
pageCursor = pageCursor,
|
||||
limit = PostRepository.DEFAULT_PAGE_SIZE,
|
||||
type = ListingType.All,
|
||||
sort = sort,
|
||||
communityId = communityId,
|
||||
)?.filter {
|
||||
)?.let {
|
||||
// prevents accidental duplication
|
||||
it.id !in currentIds
|
||||
}
|
||||
val posts = it.first
|
||||
it.copy(
|
||||
first = posts.filter { p1 ->
|
||||
p1.id !in currentIds
|
||||
},
|
||||
)
|
||||
} ?: (null to null)
|
||||
if (!result.isNullOrEmpty()) {
|
||||
currentPage++
|
||||
}
|
||||
if (nextPage != null) {
|
||||
pageCursor = nextPage
|
||||
}
|
||||
canFetchMore = result?.isEmpty() != true
|
||||
return result.orEmpty()
|
||||
}
|
||||
|
@ -55,6 +55,7 @@
|
||||
<string name="home_sort_type_top_year_short">year</string>
|
||||
<string name="home_sort_type_old">Old</string>
|
||||
<string name="home_sort_type_controversial">Controversial</string>
|
||||
<string name="home_sort_type_scaled">Scaled</string>
|
||||
<string name="home_instance_via">via %1$s</string>
|
||||
<string name="post_hour_short">h</string>
|
||||
<string name="post_minute_short">m</string>
|
||||
@ -152,6 +153,7 @@
|
||||
<string name="community_detail_info">Community info</string>
|
||||
<string name="community_detail_instance_info">Instance details</string>
|
||||
<string name="community_detail_block">Block</string>
|
||||
<string name="community_detail_block_instance">Block instance</string>
|
||||
<string name="instance_detail_title">Instance: %1$s</string>
|
||||
<string name="instance_detail_communities">Communities</string>
|
||||
<string name="action_back_to_top">Back to top</string>
|
||||
|
@ -50,6 +50,7 @@
|
||||
<string name="home_sort_type_top_week_short">semana</string>
|
||||
<string name="home_sort_type_top_year_short">año</string>
|
||||
<string name="home_sort_type_controversial">Contravertidos</string>
|
||||
<string name="home_sort_type_scaled">Proporcional</string>
|
||||
<string name="home_sort_type_old">Antiguos</string>
|
||||
<string name="home_instance_via">a través de %1$s</string>
|
||||
<string name="post_hour_short">h</string>
|
||||
@ -150,6 +151,7 @@
|
||||
<string name="community_detail_info">Info comunidad</string>
|
||||
<string name="community_detail_instance_info">Detalles instancia</string>
|
||||
<string name="community_detail_block">Bloquear</string>
|
||||
<string name="community_detail_block_instance">Bloquear instancia</string>
|
||||
<string name="instance_detail_title">Instancia: %1$s</string>
|
||||
<string name="instance_detail_communities">Comunidades</string>
|
||||
<string name="action_back_to_top">Volver arriba</string>
|
||||
|
@ -51,6 +51,7 @@
|
||||
<string name="home_sort_type_top_year_short">anno</string>
|
||||
<string name="home_sort_type_old">Vecchi</string>
|
||||
<string name="home_sort_type_controversial">Controversi</string>
|
||||
<string name="home_sort_type_scaled">Proporzionale</string>
|
||||
<string name="home_instance_via">via %1$s</string>
|
||||
<string name="post_hour_short">h</string>
|
||||
<string name="post_minute_short">m</string>
|
||||
@ -84,6 +85,7 @@
|
||||
<string name="login_field_instance_name">Nome istanza</string>
|
||||
<string name="login_field_user_name">Nome utente (o email)</string>
|
||||
<string name="community_detail_block">Blocca</string>
|
||||
<string name="community_detail_block_instance">Blocca istanza</string>
|
||||
<string name="login_field_password">Password</string>
|
||||
<string name="login_field_token">TOTP 2FA token</string>
|
||||
<string name="login_field_label_optional">(opzionale)</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user