mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 13:18:47 +01:00
feat(posts): improve post view
This commit is contained in:
parent
51a3d2b054
commit
4b80c78e30
@ -12,4 +12,8 @@ val coreApiModule = module {
|
|||||||
val provider: ServiceProvider = get()
|
val provider: ServiceProvider = get()
|
||||||
provider.postService
|
provider.postService
|
||||||
}
|
}
|
||||||
|
single {
|
||||||
|
val provider: ServiceProvider = get()
|
||||||
|
provider.communityService
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class BlockCommunityForm(
|
||||||
|
@SerialName("community_id") val communityId: CommunityId,
|
||||||
|
@SerialName("block") val block: Boolean,
|
||||||
|
@SerialName("auth") val auth: String,
|
||||||
|
)
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class BlockCommunityResponse(
|
||||||
|
@SerialName("community_view") val communityView: CommunityView,
|
||||||
|
@SerialName("blocked") val blocked: Boolean,
|
||||||
|
)
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Comment(
|
||||||
|
@SerialName("id") val id: CommentId,
|
||||||
|
@SerialName("creator_id") val creatorId: PersonId,
|
||||||
|
@SerialName("post_id") val postId: PostId,
|
||||||
|
@SerialName("content") val content: String,
|
||||||
|
@SerialName("removed") val removed: Boolean,
|
||||||
|
@SerialName("published") val published: String,
|
||||||
|
@SerialName("updated") val updated: String? = null,
|
||||||
|
@SerialName("deleted") val deleted: Boolean,
|
||||||
|
@SerialName("ap_id") val apId: String,
|
||||||
|
@SerialName("local") val local: Boolean,
|
||||||
|
@SerialName("path") val path: String,
|
||||||
|
@SerialName("distinguished") val distinguished: Boolean,
|
||||||
|
@SerialName("language_id") val languageId: LanguageId,
|
||||||
|
)
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CommentAggregates(
|
||||||
|
@SerialName("id") val id: Int,
|
||||||
|
@SerialName("comment_id") val commentId: CommentId,
|
||||||
|
@SerialName("score") val score: Int,
|
||||||
|
@SerialName("upvotes") val upvotes: Int,
|
||||||
|
@SerialName("downvotes") val downvotes: Int,
|
||||||
|
@SerialName("published") val published: String,
|
||||||
|
@SerialName("child_count") val childCount: Int,
|
||||||
|
@SerialName("hot_rank") val hotRank: Int,
|
||||||
|
)
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CommentView(
|
||||||
|
@SerialName("comment") val comment: Comment,
|
||||||
|
@SerialName("creator") val creator: Person,
|
||||||
|
@SerialName("post") val post: Post,
|
||||||
|
@SerialName("community") val community: Community,
|
||||||
|
@SerialName("counts") val counts: CommentAggregates,
|
||||||
|
@SerialName("creator_banned_from_community") val creatorBannedFromCommunity: Boolean,
|
||||||
|
@SerialName("subscribed") val subscribed: SubscribedType,
|
||||||
|
@SerialName("saved") val saved: Boolean,
|
||||||
|
@SerialName("creator_blocked") val creatorBlocked: Boolean,
|
||||||
|
@SerialName("my_vote") val myVote: Int? = null,
|
||||||
|
)
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CommunityResponse(
|
||||||
|
@SerialName("community_view") val communityView: CommunityView,
|
||||||
|
@SerialName("discussion_languages") val discussionLanguages: List<LanguageId>,
|
||||||
|
)
|
@ -6,3 +6,4 @@ typealias CommunityId = Int
|
|||||||
typealias LanguageId = Int
|
typealias LanguageId = Int
|
||||||
typealias InstanceId = Int
|
typealias InstanceId = Int
|
||||||
typealias CommentId = Int
|
typealias CommentId = Int
|
||||||
|
typealias SiteId = Int
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CreatePostForm(
|
||||||
|
@SerialName("name") val name: String,
|
||||||
|
@SerialName("community_id") val communityId: CommunityId,
|
||||||
|
@SerialName("url") val url: String? = null,
|
||||||
|
@SerialName("body") val body: String? = null,
|
||||||
|
@SerialName("honeypot") val honeypot: String? = null,
|
||||||
|
@SerialName("nsfw") val nsfw: Boolean? = null,
|
||||||
|
@SerialName("language_id") val languageId: LanguageId? = null,
|
||||||
|
@SerialName("auth") val auth: String,
|
||||||
|
)
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class DeletePostForm(
|
||||||
|
@SerialName("post_id") val postId: PostId,
|
||||||
|
@SerialName("deleted") val deleted: Boolean,
|
||||||
|
@SerialName("auth") val auth: String,
|
||||||
|
)
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class EditPostForm(
|
||||||
|
@SerialName("post_id") val postId: PostId,
|
||||||
|
@SerialName("name") val name: String? = null,
|
||||||
|
@SerialName("url") val url: String? = null,
|
||||||
|
@SerialName("body") val body: String? = null,
|
||||||
|
@SerialName("nsfw") val nsfw: Boolean? = null,
|
||||||
|
@SerialName("language_id") val languageId: LanguageId? = null,
|
||||||
|
@SerialName("auth") val auth: String,
|
||||||
|
)
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class FollowCommunityForm(
|
||||||
|
@SerialName("community_id") val communityId: CommunityId,
|
||||||
|
@SerialName("follow") val follow: Boolean,
|
||||||
|
@SerialName("auth") val auth: String,
|
||||||
|
)
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class GetCommunityResponse(
|
||||||
|
@SerialName("community_view") val communityView: CommunityView,
|
||||||
|
@SerialName("site") val site: Site? = null,
|
||||||
|
@SerialName("moderators") val moderators: List<CommunityModeratorView>,
|
||||||
|
@SerialName("discussion_languages") val discussionLanguages: List<LanguageId>,
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class GetPersonDetailsResponse(
|
||||||
|
@SerialName("person_view") val personView: PersonView,
|
||||||
|
@SerialName("comments") val comments: List<CommentView>,
|
||||||
|
@SerialName("posts") val posts: List<PostView>,
|
||||||
|
@SerialName("moderates") val moderates: List<CommunityModeratorView>,
|
||||||
|
)
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class PersonAggregates(
|
||||||
|
@SerialName("id") val id: Int,
|
||||||
|
@SerialName("person_id") val personId: PersonId,
|
||||||
|
@SerialName("post_count") val postCount: Int,
|
||||||
|
@SerialName("post_score") val postScore: Int,
|
||||||
|
@SerialName("comment_count") val commentCount: Int,
|
||||||
|
@SerialName("comment_score") val commentScore: Int,
|
||||||
|
)
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class PersonView(
|
||||||
|
@SerialName("person") val person: Person,
|
||||||
|
@SerialName("counts") val counts: PersonAggregates,
|
||||||
|
)
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class PostResponse(
|
||||||
|
@SerialName("post_view")
|
||||||
|
val postView: PostView,
|
||||||
|
)
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SavePostForm(
|
||||||
|
@SerialName("post_id") val postId: PostId,
|
||||||
|
@SerialName("save") val save: Boolean,
|
||||||
|
@SerialName("auth") val auth: String,
|
||||||
|
)
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Site(
|
||||||
|
@SerialName("id") val id: SiteId,
|
||||||
|
@SerialName("name") val name: String,
|
||||||
|
@SerialName("sidebar") val sidebar: String? = null,
|
||||||
|
@SerialName("published") val published: String,
|
||||||
|
@SerialName("updated") val updated: String? = null,
|
||||||
|
@SerialName("icon") val icon: String? = null,
|
||||||
|
@SerialName("banner") val banner: String? = null,
|
||||||
|
@SerialName("description") val description: String? = null,
|
||||||
|
@SerialName("actor_id") val actorId: String,
|
||||||
|
@SerialName("last_refreshed_at") val lastRefreshedAt: String,
|
||||||
|
@SerialName("inbox_url") val inboxUrl: String,
|
||||||
|
@SerialName("private_key") val privateKey: String? = null,
|
||||||
|
@SerialName("public_key") val publicKey: String,
|
||||||
|
@SerialName("instance_id") val instanceId: InstanceId,
|
||||||
|
)
|
@ -1,5 +1,6 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.core_api.provider
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.provider
|
||||||
|
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.service.CommunityService
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_api.service.PostService
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.service.PostService
|
||||||
import de.jensklingenberg.ktorfit.Ktorfit
|
import de.jensklingenberg.ktorfit.Ktorfit
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
@ -12,7 +13,7 @@ import kotlinx.serialization.json.Json
|
|||||||
internal class DefaultServiceProvider : ServiceProvider {
|
internal class DefaultServiceProvider : ServiceProvider {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DEFAULT_INSTANCE = "enterprise.lemmy.ml"
|
private const val DEFAULT_INSTANCE = "lemmy.world"
|
||||||
private const val VERSION = "v3"
|
private const val VERSION = "v3"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,6 +23,9 @@ internal class DefaultServiceProvider : ServiceProvider {
|
|||||||
override lateinit var postService: PostService
|
override lateinit var postService: PostService
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
override lateinit var communityService: CommunityService
|
||||||
|
private set
|
||||||
|
|
||||||
private val baseUrl: String get() = "https://$currentInstance/api/$VERSION/"
|
private val baseUrl: String get() = "https://$currentInstance/api/$VERSION/"
|
||||||
private val client = HttpClient {
|
private val client = HttpClient {
|
||||||
install(Logging) {
|
install(Logging) {
|
||||||
@ -49,5 +53,6 @@ internal class DefaultServiceProvider : ServiceProvider {
|
|||||||
.httpClient(client)
|
.httpClient(client)
|
||||||
.build()
|
.build()
|
||||||
postService = ktorfit.create()
|
postService = ktorfit.create()
|
||||||
|
communityService = ktorfit.create()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,11 +1,13 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.core_api.provider
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.provider
|
||||||
|
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.service.CommunityService
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_api.service.PostService
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.service.PostService
|
||||||
|
|
||||||
interface ServiceProvider {
|
interface ServiceProvider {
|
||||||
|
|
||||||
val currentInstance: String
|
val currentInstance: String
|
||||||
val postService: PostService
|
val postService: PostService
|
||||||
|
val communityService: CommunityService
|
||||||
|
|
||||||
fun changeInstance(value: String)
|
fun changeInstance(value: String)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.service
|
||||||
|
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.BlockCommunityForm
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.BlockCommunityResponse
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.CommunityResponse
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.FollowCommunityForm
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.GetCommunityResponse
|
||||||
|
import de.jensklingenberg.ktorfit.Response
|
||||||
|
import de.jensklingenberg.ktorfit.http.Body
|
||||||
|
import de.jensklingenberg.ktorfit.http.GET
|
||||||
|
import de.jensklingenberg.ktorfit.http.POST
|
||||||
|
import de.jensklingenberg.ktorfit.http.Query
|
||||||
|
|
||||||
|
interface CommunityService {
|
||||||
|
|
||||||
|
@GET("community")
|
||||||
|
suspend fun getCommunity(
|
||||||
|
@Query("auth") auth: String? = null,
|
||||||
|
@Query("id") id: Int? = null,
|
||||||
|
@Query("name") name: String? = null,
|
||||||
|
): Response<GetCommunityResponse>
|
||||||
|
|
||||||
|
@POST("community/follow")
|
||||||
|
suspend fun followCommunity(@Body form: FollowCommunityForm): Response<CommunityResponse>
|
||||||
|
|
||||||
|
@POST("community/block")
|
||||||
|
suspend fun blockCommunity(@Body form: BlockCommunityForm): Response<BlockCommunityResponse>
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,19 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.core_api.service
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.service
|
||||||
|
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.CreatePostForm
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.DeletePostForm
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.EditPostForm
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.GetPostResponse
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.GetPostResponse
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.GetPostsResponse
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.GetPostsResponse
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.ListingType
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.ListingType
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.PostResponse
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.SavePostForm
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.SortType
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.SortType
|
||||||
import de.jensklingenberg.ktorfit.Response
|
import de.jensklingenberg.ktorfit.Response
|
||||||
|
import de.jensklingenberg.ktorfit.http.Body
|
||||||
import de.jensklingenberg.ktorfit.http.GET
|
import de.jensklingenberg.ktorfit.http.GET
|
||||||
|
import de.jensklingenberg.ktorfit.http.POST
|
||||||
|
import de.jensklingenberg.ktorfit.http.PUT
|
||||||
import de.jensklingenberg.ktorfit.http.Query
|
import de.jensklingenberg.ktorfit.http.Query
|
||||||
|
|
||||||
interface PostService {
|
interface PostService {
|
||||||
@ -28,4 +36,17 @@ interface PostService {
|
|||||||
@Query("id") id: Int? = null,
|
@Query("id") id: Int? = null,
|
||||||
@Query("comment_id") commentId: Int? = null,
|
@Query("comment_id") commentId: Int? = null,
|
||||||
): Response<GetPostResponse>
|
): Response<GetPostResponse>
|
||||||
|
|
||||||
|
@PUT("post/save")
|
||||||
|
suspend fun savePost(@Body form: SavePostForm): Response<PostResponse>
|
||||||
|
|
||||||
|
@POST("post")
|
||||||
|
suspend fun createPost(@Body form: CreatePostForm): Response<PostResponse>
|
||||||
|
|
||||||
|
@PUT("post")
|
||||||
|
suspend fun editPost(@Body form: EditPostForm): Response<PostResponse>
|
||||||
|
|
||||||
|
@POST("post/delete")
|
||||||
|
suspend fun deletePost(@Body form: DeletePostForm): Response<PostResponse>
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.core_api.service
|
||||||
|
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.GetPersonDetailsResponse
|
||||||
|
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.Query
|
||||||
|
|
||||||
|
interface UserService {
|
||||||
|
|
||||||
|
@GET("user")
|
||||||
|
suspend fun getPersonDetails(
|
||||||
|
@Query("auth") auth: String? = null,
|
||||||
|
@Query("community_id") communityId: Int? = null,
|
||||||
|
@Query("person_id") personId: Int? = null,
|
||||||
|
@Query("page") page: Int? = null,
|
||||||
|
@Query("limit") limit: Int? = null,
|
||||||
|
@Query("sort") sort: SortType,
|
||||||
|
@Query("username") username: String? = null,
|
||||||
|
@Query("saved_only") savedOnly: Boolean? = null,
|
||||||
|
): Response<GetPersonDetailsResponse>
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.data
|
||||||
|
|
||||||
|
data class CommunityModel(
|
||||||
|
val id: Int = 0,
|
||||||
|
val name: String = "",
|
||||||
|
val instance: String = "",
|
||||||
|
val icon: String? = null,
|
||||||
|
)
|
@ -1,6 +1,11 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.data
|
package com.github.diegoberaldin.raccoonforlemmy.data
|
||||||
|
|
||||||
data class PostModel(
|
data class PostModel(
|
||||||
|
val id: Int = 0,
|
||||||
val title: String = "",
|
val title: String = "",
|
||||||
val text: String = "",
|
val text: String = "",
|
||||||
|
val score: Int = 0,
|
||||||
|
val comments: Int = 0,
|
||||||
|
val thumbnailUrl: String? = null,
|
||||||
|
val community: CommunityModel? = null,
|
||||||
)
|
)
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.data
|
||||||
|
|
||||||
|
data class UserModel(
|
||||||
|
val name: String = "",
|
||||||
|
)
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.domain_post.repository
|
||||||
|
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.CommunityView
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.service.CommunityService
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.data.CommunityModel
|
||||||
|
|
||||||
|
class CommunityRepository(
|
||||||
|
private val communityService: CommunityService,
|
||||||
|
) {
|
||||||
|
|
||||||
|
suspend fun getCommunity(id: Int): CommunityModel? {
|
||||||
|
val response = communityService.getCommunity(id = id).body()
|
||||||
|
return response?.communityView?.toModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CommunityView.toModel() = CommunityModel(
|
||||||
|
name = community.name,
|
||||||
|
icon = community.icon,
|
||||||
|
)
|
@ -2,6 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.domain_post.repository
|
|||||||
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.PostView
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.dto.PostView
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_api.service.PostService
|
import com.github.diegoberaldin.raccoonforlemmy.core_api.service.PostService
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.data.CommunityModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.data.ListingType
|
import com.github.diegoberaldin.raccoonforlemmy.data.ListingType
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.data.PostModel
|
import com.github.diegoberaldin.raccoonforlemmy.data.PostModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.data.SortType
|
import com.github.diegoberaldin.raccoonforlemmy.data.SortType
|
||||||
@ -34,8 +35,13 @@ class PostsRepository(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun PostView.toModel() = PostModel(
|
private fun PostView.toModel() = PostModel(
|
||||||
title = this.post.name,
|
id = post.id,
|
||||||
text = this.post.body.orEmpty(),
|
title = post.name,
|
||||||
|
text = post.body.orEmpty(),
|
||||||
|
score = counts.score,
|
||||||
|
comments = counts.comments,
|
||||||
|
thumbnailUrl = post.thumbnailUrl.orEmpty(),
|
||||||
|
community = CommunityModel(id = post.communityId)
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun ListingType.toDto() = when (this) {
|
private fun ListingType.toDto() = when (this) {
|
||||||
|
@ -4,6 +4,7 @@ import org.koin.core.module.dsl.singleOf
|
|||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
val postsRepositoryModule = module {
|
val postsRepositoryModule = module {
|
||||||
singleOf(::PostsRepository)
|
|
||||||
singleOf(::ApiConfigurationRepository)
|
singleOf(::ApiConfigurationRepository)
|
||||||
|
singleOf(::PostsRepository)
|
||||||
|
singleOf(::CommunityRepository)
|
||||||
}
|
}
|
@ -45,6 +45,7 @@ kotlin {
|
|||||||
|
|
||||||
implementation(libs.voyager.navigator)
|
implementation(libs.voyager.navigator)
|
||||||
implementation(libs.voyager.tab)
|
implementation(libs.voyager.tab)
|
||||||
|
implementation(libs.compose.imageloader)
|
||||||
|
|
||||||
implementation(projects.resources)
|
implementation(projects.resources)
|
||||||
implementation(projects.coreAppearance)
|
implementation(projects.coreAppearance)
|
||||||
|
@ -11,6 +11,7 @@ actual val homeTabModule = module {
|
|||||||
HomeScreenModel(
|
HomeScreenModel(
|
||||||
mvi = DefaultMviModel(HomeScreenMviModel.UiState()),
|
mvi = DefaultMviModel(HomeScreenMviModel.UiState()),
|
||||||
postsRepository = get(),
|
postsRepository = get(),
|
||||||
|
communityRepository = get(),
|
||||||
apiConfigRepository = get(),
|
apiConfigRepository = get(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core_architecture.MviModel
|
|||||||
import com.github.diegoberaldin.raccoonforlemmy.data.ListingType
|
import com.github.diegoberaldin.raccoonforlemmy.data.ListingType
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.data.SortType
|
import com.github.diegoberaldin.raccoonforlemmy.data.SortType
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain_post.repository.ApiConfigurationRepository
|
import com.github.diegoberaldin.raccoonforlemmy.domain_post.repository.ApiConfigurationRepository
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.domain_post.repository.CommunityRepository
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain_post.repository.PostsRepository
|
import com.github.diegoberaldin.raccoonforlemmy.domain_post.repository.PostsRepository
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.IO
|
import kotlinx.coroutines.IO
|
||||||
@ -14,6 +15,7 @@ import kotlinx.coroutines.launch
|
|||||||
class HomeScreenModel(
|
class HomeScreenModel(
|
||||||
private val mvi: DefaultMviModel<HomeScreenMviModel.Intent, HomeScreenMviModel.UiState, HomeScreenMviModel.Effect>,
|
private val mvi: DefaultMviModel<HomeScreenMviModel.Intent, HomeScreenMviModel.UiState, HomeScreenMviModel.Effect>,
|
||||||
private val postsRepository: PostsRepository,
|
private val postsRepository: PostsRepository,
|
||||||
|
private val communityRepository: CommunityRepository,
|
||||||
private val apiConfigRepository: ApiConfigurationRepository,
|
private val apiConfigRepository: ApiConfigurationRepository,
|
||||||
) : ScreenModel,
|
) : ScreenModel,
|
||||||
MviModel<HomeScreenMviModel.Intent, HomeScreenMviModel.UiState, HomeScreenMviModel.Effect> by mvi {
|
MviModel<HomeScreenMviModel.Intent, HomeScreenMviModel.UiState, HomeScreenMviModel.Effect> by mvi {
|
||||||
@ -56,12 +58,30 @@ class HomeScreenModel(
|
|||||||
page = currentPage,
|
page = currentPage,
|
||||||
type = type,
|
type = type,
|
||||||
sort = sort,
|
sort = sort,
|
||||||
)
|
).map {
|
||||||
|
val community = it.community
|
||||||
|
if (community?.id != null) {
|
||||||
|
val remoteCommunity = communityRepository.getCommunity(community.id)
|
||||||
|
it.copy(
|
||||||
|
community = it.community?.copy(
|
||||||
|
name = remoteCommunity?.name.orEmpty(),
|
||||||
|
icon = remoteCommunity?.icon,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
currentPage++
|
currentPage++
|
||||||
val canFetchMore = postList.size >= PostsRepository.DEFAULT_PAGE_SIZE
|
val canFetchMore = postList.size >= PostsRepository.DEFAULT_PAGE_SIZE
|
||||||
mvi.updateState {
|
mvi.updateState {
|
||||||
|
val newPosts = if (refreshing) {
|
||||||
|
postList
|
||||||
|
} else {
|
||||||
|
it.posts + postList
|
||||||
|
}
|
||||||
it.copy(
|
it.copy(
|
||||||
posts = if (refreshing) postList else it.posts + postList,
|
posts = newPosts,
|
||||||
loading = false,
|
loading = false,
|
||||||
canFetchMore = canFetchMore,
|
canFetchMore = canFetchMore,
|
||||||
refreshing = false,
|
refreshing = false,
|
||||||
|
@ -1,49 +1,36 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.feature_home
|
package com.github.diegoberaldin.raccoonforlemmy.feature_home
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.SpaceDashboard
|
import androidx.compose.material.icons.filled.SpaceDashboard
|
||||||
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
||||||
import androidx.compose.material.pullrefresh.pullRefresh
|
import androidx.compose.material.pullrefresh.pullRefresh
|
||||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||||
import androidx.compose.material3.Card
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
|
||||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.tab.Tab
|
import cafe.adriel.voyager.navigator.tab.Tab
|
||||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||||
import com.github.diegoberaldin.racconforlemmy.core_utils.onClick
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_appearance.theme.CornerSize
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_appearance.theme.Spacing
|
import com.github.diegoberaldin.raccoonforlemmy.core_appearance.theme.Spacing
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_architecture.bindToLifecycle
|
import com.github.diegoberaldin.raccoonforlemmy.core_architecture.bindToLifecycle
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core_md.compose.Markdown
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.feature_home.modals.ListingTypeBottomSheet
|
import com.github.diegoberaldin.raccoonforlemmy.feature_home.modals.ListingTypeBottomSheet
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.feature_home.modals.SortBottomSheet
|
import com.github.diegoberaldin.raccoonforlemmy.feature_home.modals.SortBottomSheet
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||||
@ -81,7 +68,27 @@ object HomeTab : Tab {
|
|||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.padding(Spacing.xxs),
|
modifier = Modifier.padding(Spacing.xxs),
|
||||||
topBar = {
|
topBar = {
|
||||||
PostsTopBar(model, uiState)
|
PostsTopBar(
|
||||||
|
currentInstance = uiState.instance,
|
||||||
|
listingType = uiState.listingType,
|
||||||
|
sortType = uiState.sortType,
|
||||||
|
onSelectListingType = {
|
||||||
|
bottomSheetChannel.trySend @Composable {
|
||||||
|
ListingTypeBottomSheet { type ->
|
||||||
|
model.reduce(HomeScreenMviModel.Intent.ChangeListing(type))
|
||||||
|
bottomSheetChannel.trySend(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSelectSortType = {
|
||||||
|
bottomSheetChannel.trySend @Composable {
|
||||||
|
SortBottomSheet { type ->
|
||||||
|
model.reduce(HomeScreenMviModel.Intent.ChangeSort(type))
|
||||||
|
bottomSheetChannel.trySend(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
val pullRefreshState = rememberPullRefreshState(uiState.refreshing, {
|
val pullRefreshState = rememberPullRefreshState(uiState.refreshing, {
|
||||||
@ -95,25 +102,7 @@ object HomeTab : Tab {
|
|||||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs)
|
verticalArrangement = Arrangement.spacedBy(Spacing.xs)
|
||||||
) {
|
) {
|
||||||
items(uiState.posts) { post ->
|
items(uiState.posts) { post ->
|
||||||
Card(
|
PostCard(post)
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.background(
|
|
||||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
|
||||||
shape = RoundedCornerShape(CornerSize.m)
|
|
||||||
).padding(Spacing.s)
|
|
||||||
) {
|
|
||||||
Column {
|
|
||||||
Text(
|
|
||||||
text = post.title,
|
|
||||||
style = MaterialTheme.typography.titleMedium,
|
|
||||||
)
|
|
||||||
val body = post.text
|
|
||||||
if (body.isNotEmpty()) {
|
|
||||||
Markdown(content = body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
if (!uiState.loading && !uiState.refreshing && uiState.canFetchMore) {
|
if (!uiState.loading && !uiState.refreshing && uiState.canFetchMore) {
|
||||||
@ -143,65 +132,4 @@ object HomeTab : Tab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun PostsTopBar(
|
|
||||||
model: HomeScreenModel,
|
|
||||||
uiState: HomeScreenMviModel.UiState,
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.height(64.dp).padding(Spacing.s),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.onClick {
|
|
||||||
bottomSheetChannel.trySend @Composable {
|
|
||||||
ListingTypeBottomSheet { type ->
|
|
||||||
model.reduce(HomeScreenMviModel.Intent.ChangeListing(type))
|
|
||||||
bottomSheetChannel.trySend(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(Spacing.m),
|
|
||||||
) {
|
|
||||||
Image(
|
|
||||||
imageVector = uiState.listingType.toIcon(),
|
|
||||||
contentDescription = null,
|
|
||||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground)
|
|
||||||
)
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.spacedBy(Spacing.xxxs)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = uiState.listingType.toReadableName(),
|
|
||||||
style = MaterialTheme.typography.titleMedium
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = stringResource(
|
|
||||||
MR.strings.home_instance_via,
|
|
||||||
uiState.instance
|
|
||||||
),
|
|
||||||
style = MaterialTheme.typography.titleSmall
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
|
||||||
|
|
||||||
Image(
|
|
||||||
modifier = Modifier.onClick {
|
|
||||||
bottomSheetChannel.trySend @Composable {
|
|
||||||
SortBottomSheet { type ->
|
|
||||||
model.reduce(HomeScreenMviModel.Intent.ChangeSort(type))
|
|
||||||
bottomSheetChannel.trySend(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
imageVector = uiState.sortType.toIcon(),
|
|
||||||
contentDescription = null,
|
|
||||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,128 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.feature_home
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.ArrowDropDown
|
||||||
|
import androidx.compose.material.icons.filled.ArrowDropUp
|
||||||
|
import androidx.compose.material.icons.filled.Chat
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_appearance.theme.CornerSize
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_appearance.theme.Spacing
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_md.compose.Markdown
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.data.PostModel
|
||||||
|
import com.seiko.imageloader.rememberImagePainter
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PostCard(
|
||||||
|
post: PostModel,
|
||||||
|
) {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(
|
||||||
|
color = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
shape = RoundedCornerShape(CornerSize.m)
|
||||||
|
).padding(
|
||||||
|
vertical = Spacing.lHalf,
|
||||||
|
horizontal = Spacing.s,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(Spacing.s)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = post.title,
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
)
|
||||||
|
|
||||||
|
val communityName = post.community?.name.orEmpty()
|
||||||
|
val communityIcon = post.community?.icon.orEmpty()
|
||||||
|
val iconSize = 21.dp
|
||||||
|
if (communityName.isNotEmpty()) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||||
|
) {
|
||||||
|
if (communityIcon.isNotEmpty()) {
|
||||||
|
val painter = rememberImagePainter(communityIcon)
|
||||||
|
Image(
|
||||||
|
modifier = Modifier.size(iconSize)
|
||||||
|
.clip(RoundedCornerShape(iconSize / 2)),
|
||||||
|
painter = painter,
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.FillWidth,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = communityName,
|
||||||
|
style = MaterialTheme.typography.titleSmall,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val imageUrl = post.thumbnailUrl
|
||||||
|
if (!imageUrl.isNullOrEmpty()) {
|
||||||
|
val painter = rememberImagePainter(imageUrl)
|
||||||
|
Image(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
painter = painter,
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.FillWidth,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val body = post.text
|
||||||
|
if (body.isNotEmpty()) {
|
||||||
|
Markdown(content = body)
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(Spacing.xxs),
|
||||||
|
) {
|
||||||
|
val buttonModifier = Modifier.size(42.dp)
|
||||||
|
Image(
|
||||||
|
modifier = buttonModifier,
|
||||||
|
imageVector = Icons.Default.ArrowDropUp,
|
||||||
|
contentDescription = null,
|
||||||
|
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.onSurface)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "${post.score}"
|
||||||
|
)
|
||||||
|
Image(
|
||||||
|
modifier = buttonModifier,
|
||||||
|
imageVector = Icons.Default.ArrowDropDown,
|
||||||
|
contentDescription = null,
|
||||||
|
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.onSurface)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
Image(
|
||||||
|
modifier = buttonModifier.padding(10.dp),
|
||||||
|
imageVector = Icons.Default.Chat,
|
||||||
|
contentDescription = null,
|
||||||
|
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.onSurface)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "${post.comments}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.feature_home
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.github.diegoberaldin.racconforlemmy.core_utils.onClick
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core_appearance.theme.Spacing
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.data.ListingType
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.data.SortType
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||||
|
import dev.icerock.moko.resources.compose.stringResource
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun PostsTopBar(
|
||||||
|
currentInstance: String,
|
||||||
|
listingType: ListingType,
|
||||||
|
sortType: SortType,
|
||||||
|
onSelectListingType: () -> Unit,
|
||||||
|
onSelectSortType: () -> Unit,
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.height(64.dp).padding(Spacing.s),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.onClick {
|
||||||
|
onSelectListingType()
|
||||||
|
},
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(Spacing.m),
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
imageVector = listingType.toIcon(),
|
||||||
|
contentDescription = null,
|
||||||
|
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground)
|
||||||
|
)
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(Spacing.xxxs)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = listingType.toReadableName(),
|
||||||
|
style = MaterialTheme.typography.titleMedium
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = stringResource(
|
||||||
|
MR.strings.home_instance_via,
|
||||||
|
currentInstance,
|
||||||
|
),
|
||||||
|
style = MaterialTheme.typography.titleSmall
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
|
Image(
|
||||||
|
modifier = Modifier.onClick {
|
||||||
|
onSelectSortType()
|
||||||
|
},
|
||||||
|
imageVector = sortType.toIcon(),
|
||||||
|
contentDescription = null,
|
||||||
|
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -38,6 +38,7 @@ kotlin {
|
|||||||
implementation(compose.runtime)
|
implementation(compose.runtime)
|
||||||
implementation(compose.foundation)
|
implementation(compose.foundation)
|
||||||
implementation(compose.material3)
|
implementation(compose.material3)
|
||||||
|
implementation(compose.materialIconsExtended)
|
||||||
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
|
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
|
||||||
implementation(compose.components.resources)
|
implementation(compose.components.resources)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package com.github.diegoberaldin.raccoonforlemmy.feature_search
|
|||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Search
|
import androidx.compose.material.icons.filled.Explore
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -23,7 +23,7 @@ object SearchTab : Tab {
|
|||||||
@Composable
|
@Composable
|
||||||
get() {
|
get() {
|
||||||
val title = stringResource(MR.strings.navigation_search)
|
val title = stringResource(MR.strings.navigation_search)
|
||||||
val icon = rememberVectorPainter(Icons.Default.Search)
|
val icon = rememberVectorPainter(Icons.Default.Explore)
|
||||||
|
|
||||||
return remember {
|
return remember {
|
||||||
TabOptions(
|
TabOptions(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user