diff --git a/app/build.gradle b/app/build.gradle index 36c7a443..682da7e9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -122,6 +122,10 @@ dependencies { implementation "com.kakao.sdk:v2-user:2.19.0" //naver login implementation 'com.navercorp.nid:oauth:5.1.1' + + implementation "androidx.room:room-runtime:2.6.1" + kapt "androidx.room:room-compiler:2.6.1" + implementation "androidx.room:room-ktx:2.6.1" } kapt { correctErrorTypes true diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 39b5c98d..75480b71 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,6 +48,7 @@ android:exported="false" /> - - - - - + + + + + diff --git a/app/src/main/java/com/umc/ttoklip/data/api/NewsApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/NewsApi.kt index de319133..e300320f 100644 --- a/app/src/main/java/com/umc/ttoklip/data/api/NewsApi.kt +++ b/app/src/main/java/com/umc/ttoklip/data/api/NewsApi.kt @@ -1,14 +1,72 @@ package com.umc.ttoklip.data.api +import com.umc.ttoklip.data.model.CommonResponse import com.umc.ttoklip.data.model.ResponseBody -import com.umc.ttoklip.data.model.TestResponse import com.umc.ttoklip.data.model.news.MainNewsResponse +import com.umc.ttoklip.data.model.news.ReportRequest +import com.umc.ttoklip.data.model.news.comment.NewsCommentRequest +import com.umc.ttoklip.data.model.news.detail.NewsDetailResponse import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.DELETE import retrofit2.http.GET +import retrofit2.http.PATCH +import retrofit2.http.POST +import retrofit2.http.Path +import retrofit2.http.Query interface NewsApi { @GET("/api/v1/newsletters/posts") suspend fun getNewsMainApi(): Response> + @GET("/api/v1/newsletter/posts/{postId}") + suspend fun getDetailNewsApi( + @Path("postId") postId : Int + ): Response> + + @POST("/api/v1/newsletter/comment/{postId}") + suspend fun postCommentNewsApi( + @Path("postId") postId: Int, + @Body request : NewsCommentRequest + ): Response> + + @POST("/api/v1/newsletter/posts/report/{postId}") + suspend fun postReportNewsApi( + @Path("postId") postId: Int, + @Body request : ReportRequest + ): Response> + + @POST("/api/v1/newsletter/comment/report/{commentId}") + suspend fun postReportCommentNewsApi( + @Path("commentId") commentId: Int, + @Body request : ReportRequest + ): Response> + + + @DELETE("/api/v1/newsletter/comment/{commentId}") + suspend fun deleteCommentNewsApi( + @Path("commentId") commentId: Int, + ): Response> + + @POST("/api/v1/newsletter/posts/like/{postId}") + suspend fun postLikeNewsApi( + @Path("postId") postId: Int, + ): Response> + + @DELETE("/api/v1/newsletter/posts/like/{postId}") + suspend fun deleteLikeNewsApi( + @Path("postId") postId: Int, + ): Response> + + @POST("/api/v1/newsletter/posts/scrap/{postId}") + suspend fun postScrapNewsApi( + @Path("postId") postId: Int, + ): Response> + + @DELETE("/api/v1/newsletter/posts/scrap/{postId}") + suspend fun deleteScrapNewsApi( + @Path("postId") postId: Int, + ): Response> + } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/SearchApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/SearchApi.kt new file mode 100644 index 00000000..5925ddd5 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/api/SearchApi.kt @@ -0,0 +1,33 @@ +package com.umc.ttoklip.data.api + +import com.umc.ttoklip.data.model.ResponseBody +import com.umc.ttoklip.data.model.news.detail.NewsDetailResponse +import com.umc.ttoklip.data.model.search.NewsSearchResponse +import com.umc.ttoklip.data.model.search.TipSearchResponse +import com.umc.ttoklip.data.model.search.TownSearchResponse +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Query + +interface SearchApi { + + @GET("/api/v1/search/newsletter") + suspend fun getSearchNewsApi( + @Query("title") title : String, + @Query("sort") sort: String + ): Response> + + @GET("/api/v1/search/honeytip") + suspend fun getSearchTipApi( + @Query("title") title : String, + @Query("sort") sort: String + ): Response> + + + @GET("/api/v1/search/our-town") + suspend fun getSearchTownApi( + @Query("title") title : String, + @Query("sort") sort: String + ): Response> + +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/db/DBUtile.kt b/app/src/main/java/com/umc/ttoklip/data/db/DBUtile.kt new file mode 100644 index 00000000..2bcfd7f4 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/db/DBUtile.kt @@ -0,0 +1,42 @@ +package com.umc.ttoklip.data.db + +import androidx.room.Dao +import androidx.room.Database +import androidx.room.Entity +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.PrimaryKey +import androidx.room.Query +import androidx.room.RoomDatabase + +@Database( + entities = [HistoryEntity::class], + version = 1, + exportSchema = false +) +abstract class AppDatabase : RoomDatabase() { + abstract fun historyDao(): HistoryDao +} + +@Dao +interface HistoryDao { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun addHistory(item: HistoryEntity) + + @Query("SELECT * FROM HistoryEntity") + suspend fun getAll(): List + + @Query("DELETE FROM HistoryEntity") + suspend fun deleteAll() +} + +@Entity +data class HistoryEntity( + @PrimaryKey(autoGenerate = true) val id: Int , + val history: String +) { + companion object { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/CommonResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/CommonResponse.kt new file mode 100644 index 00000000..b39d942c --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/CommonResponse.kt @@ -0,0 +1,5 @@ +package com.umc.ttoklip.data.model + +data class CommonResponse( + val message : String +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/CategoryResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/CategoryResponse.kt deleted file mode 100644 index db5c1f86..00000000 --- a/app/src/main/java/com/umc/ttoklip/data/model/news/CategoryResponse.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.umc.ttoklip.data.model.news - -data class CategoryResponse( - val cookingQuestions: List, - val houseworkQuestions: List, - val safeLivingQuestions: List, - val welfarePolicyQuestions: List -) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/CategoryResponses.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/CategoryResponses.kt new file mode 100644 index 00000000..dffa2e7d --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/news/CategoryResponses.kt @@ -0,0 +1,8 @@ +package com.umc.ttoklip.data.model.news + +data class CategoryResponses( + val houseWork: List, + val recipe: List, + val safeLiving: List, + val welfarePolicy: List +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/CookingQuestion.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/CookingQuestion.kt deleted file mode 100644 index 5597991d..00000000 --- a/app/src/main/java/com/umc/ttoklip/data/model/news/CookingQuestion.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.umc.ttoklip.data.model.news - -data class CookingQuestion( - val category: String, - val commentCount: Int, - val content: String, - val questionId: Int, - val title: String, - val writer: String, - val writtenTime: String -) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/HouseworkQuestion.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/HouseworkQuestion.kt deleted file mode 100644 index b67e0ecc..00000000 --- a/app/src/main/java/com/umc/ttoklip/data/model/news/HouseworkQuestion.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.umc.ttoklip.data.model.news - -data class HouseworkQuestion( - val category: String, - val commentCount: Int, - val content: String, - val questionId: Int, - val title: String, - val writer: String, - val writtenTime: String -) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/MainNewsResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/MainNewsResponse.kt index fb0ff1b5..249003e3 100644 --- a/app/src/main/java/com/umc/ttoklip/data/model/news/MainNewsResponse.kt +++ b/app/src/main/java/com/umc/ttoklip/data/model/news/MainNewsResponse.kt @@ -1,6 +1,6 @@ package com.umc.ttoklip.data.model.news data class MainNewsResponse( - val categoryResponse: CategoryResponse, - val topFiveQuestions: List + val categoryResponses: CategoryResponses, + val randomNews: List ) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/News.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/News.kt new file mode 100644 index 00000000..05e2ff97 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/news/News.kt @@ -0,0 +1,10 @@ +package com.umc.ttoklip.data.model.news + +data class News( + val mainImageUrl: String, + val newsletterId: Int, + val title: String, + val writtenTime: String +){ + constructor() : this("",0,"","") +} diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/ReportRequest.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/ReportRequest.kt new file mode 100644 index 00000000..8c621fd4 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/news/ReportRequest.kt @@ -0,0 +1,6 @@ +package com.umc.ttoklip.data.model.news + +data class ReportRequest( + val content: String, + val reportType: String +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/SafeLivingQuestion.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/SafeLivingQuestion.kt deleted file mode 100644 index a35cbfae..00000000 --- a/app/src/main/java/com/umc/ttoklip/data/model/news/SafeLivingQuestion.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.umc.ttoklip.data.model.news - -data class SafeLivingQuestion( - val category: String, - val commentCount: Int, - val content: String, - val questionId: Int, - val title: String, - val writer: String, - val writtenTime: String -) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/TopFiveQuestion.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/TopFiveQuestion.kt deleted file mode 100644 index a5125e1c..00000000 --- a/app/src/main/java/com/umc/ttoklip/data/model/news/TopFiveQuestion.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.umc.ttoklip.data.model.news - -data class TopFiveQuestion( - val category: String, - val commentCount: Int, - val content: String, - val questionId: Int, - val title: String, - val writer: String, - val writtenTime: String -) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/WelfarePolicyQuestion.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/WelfarePolicyQuestion.kt deleted file mode 100644 index 0f54e970..00000000 --- a/app/src/main/java/com/umc/ttoklip/data/model/news/WelfarePolicyQuestion.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.umc.ttoklip.data.model.news - -data class WelfarePolicyQuestion( - val category: String, - val commentCount: Int, - val content: String, - val questionId: Int, - val title: String, - val writer: String, - val writtenTime: String -) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/comment/NewsCommentRequest.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/comment/NewsCommentRequest.kt new file mode 100644 index 00000000..2cb8de48 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/news/comment/NewsCommentRequest.kt @@ -0,0 +1,6 @@ +package com.umc.ttoklip.data.model.news.comment + +data class NewsCommentRequest( + val comment: String, + val parentCommentId: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/comment/NewsCommentResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/comment/NewsCommentResponse.kt new file mode 100644 index 00000000..663386c3 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/news/comment/NewsCommentResponse.kt @@ -0,0 +1,9 @@ +package com.umc.ttoklip.data.model.news.comment + +data class NewsCommentResponse( + val commentContent: String, + val commentId: Int, + val parentId: Int?, + val writer: String?, + val writtenTime: String +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/detail/ImageUrl.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/detail/ImageUrl.kt new file mode 100644 index 00000000..b814c518 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/news/detail/ImageUrl.kt @@ -0,0 +1,5 @@ +package com.umc.ttoklip.data.model.news.detail + +data class ImageUrl( + val imageUrl : String +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/detail/NewsDetailResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/detail/NewsDetailResponse.kt new file mode 100644 index 00000000..812a5e09 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/news/detail/NewsDetailResponse.kt @@ -0,0 +1,21 @@ +package com.umc.ttoklip.data.model.news.detail + +import com.umc.ttoklip.data.model.news.comment.NewsCommentResponse + +data class NewsDetailResponse( + val category: String, + val commentResponses: List, + val content: String, + val imageUrlList: List, + val newsletterId: Int, + var likeCount: Int, + var scrapCount: Int, + val title: String?, + val urlList: List, + val writer: String?, + val writtenTime: String, + val likedByCurrentUser: Boolean, + val scrapedByCurrentUser: Boolean +) { + constructor() : this("", listOf(), "", listOf(), 0, 0, 0, "", listOf(), "", "", false, false) +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/news/detail/Url.kt b/app/src/main/java/com/umc/ttoklip/data/model/news/detail/Url.kt new file mode 100644 index 00000000..45100dc9 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/news/detail/Url.kt @@ -0,0 +1,5 @@ +package com.umc.ttoklip.data.model.news.detail + +data class Url( + val url: String +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/search/NewsSearchResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/search/NewsSearchResponse.kt new file mode 100644 index 00000000..092c8487 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/search/NewsSearchResponse.kt @@ -0,0 +1,9 @@ +package com.umc.ttoklip.data.model.search + +data class NewsSearchResponse( + val isFirst: Boolean, + val isLast: Boolean, + val newsletters: List, + val totalElements: Int, + val totalPage: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/search/SearchModel.kt b/app/src/main/java/com/umc/ttoklip/data/model/search/SearchModel.kt new file mode 100644 index 00000000..c518a25c --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/search/SearchModel.kt @@ -0,0 +1,13 @@ +package com.umc.ttoklip.data.model.search + +data class SearchModel( + val category: String, + val commentCount: Int, + val content: String, + val id: Int, + val title: String, + val bigCategory : Int, + val likeCount: Int, + val scrapCount : Int, + val writer : String +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/search/SearchNoResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/search/SearchNoResponse.kt new file mode 100644 index 00000000..886eed5f --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/search/SearchNoResponse.kt @@ -0,0 +1,16 @@ +package com.umc.ttoklip.data.model.search + +data class SearchNoResponse( + val category: String, + val commentCount: Int, + val content: String, + val id: Int, + val likeCount: Int, + val scrapCount: Int, + val title: String, + val writer: String? +) { + fun toModel(category: String, bigCategory: Int) = SearchModel( + category, commentCount, content, id, title, bigCategory , likeCount, scrapCount , writer ?: "" + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/search/SearchResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/search/SearchResponse.kt new file mode 100644 index 00000000..f1e088d6 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/search/SearchResponse.kt @@ -0,0 +1,16 @@ +package com.umc.ttoklip.data.model.search + +data class SearchResponse( + val category: String, + val commentCount: Int, + val content: String, + val id: Int, + val likeCount: Int, + val scrapCount: Int, + val title: String, + val writer: String? +){ + fun toModel(bigCategory: Int) = SearchModel( + category, commentCount, content, id, title, bigCategory ,likeCount, scrapCount , writer ?: "" + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/search/TipSearchResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/search/TipSearchResponse.kt new file mode 100644 index 00000000..175741f4 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/search/TipSearchResponse.kt @@ -0,0 +1,9 @@ +package com.umc.ttoklip.data.model.search + +data class TipSearchResponse( + val isFirst: Boolean, + val isLast: Boolean, + val honeyTips: List, + val totalElements: Int, + val totalPage: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/search/TownSearchResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/search/TownSearchResponse.kt new file mode 100644 index 00000000..1cf53470 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/search/TownSearchResponse.kt @@ -0,0 +1,9 @@ +package com.umc.ttoklip.data.model.search + +data class TownSearchResponse( + val isFirst: Boolean, + val isLast: Boolean, + val communities: List, + val totalElements: Int, + val totalPage: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/news/NewsRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/news/NewsRepository.kt index 6837c775..f4cd71a8 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/news/NewsRepository.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/news/NewsRepository.kt @@ -1,9 +1,30 @@ package com.umc.ttoklip.data.repository.news +import com.umc.ttoklip.data.model.CommonResponse import com.umc.ttoklip.data.model.news.MainNewsResponse +import com.umc.ttoklip.data.model.news.ReportRequest +import com.umc.ttoklip.data.model.news.comment.NewsCommentRequest +import com.umc.ttoklip.data.model.news.detail.NewsDetailResponse import com.umc.ttoklip.module.NetworkResult interface NewsRepository { suspend fun getNewsMain(): NetworkResult + suspend fun getDetailNews(postId :Int): NetworkResult + suspend fun postCommentNews(postId: Int, request : NewsCommentRequest): NetworkResult + + suspend fun postReportNews(postId: Int, request : ReportRequest): NetworkResult + + suspend fun postReportCommentNews(postId: Int, request : ReportRequest): NetworkResult + + suspend fun deleteCommentNews(postId: Int): NetworkResult + + suspend fun postLikeNews(postId: Int): NetworkResult + + suspend fun deleteLikeNews(postId: Int): NetworkResult + + suspend fun postScrapNews(postId: Int): NetworkResult + + suspend fun deleteScrapNews(postId: Int): NetworkResult + } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/news/NewsRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/news/NewsRepositoryImpl.kt index 205155be..91cd7888 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/news/NewsRepositoryImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/news/NewsRepositoryImpl.kt @@ -1,8 +1,12 @@ package com.umc.ttoklip.data.repository.news import com.umc.ttoklip.data.api.NewsApi +import com.umc.ttoklip.data.model.CommonResponse import com.umc.ttoklip.data.model.ResponseBody import com.umc.ttoklip.data.model.news.MainNewsResponse +import com.umc.ttoklip.data.model.news.ReportRequest +import com.umc.ttoklip.data.model.news.comment.NewsCommentRequest +import com.umc.ttoklip.data.model.news.detail.NewsDetailResponse import com.umc.ttoklip.module.NetworkResult import com.umc.ttoklip.module.handleApi import javax.inject.Inject @@ -15,4 +19,47 @@ class NewsRepositoryImpl @Inject constructor( return handleApi({api.getNewsMainApi()}) {response: ResponseBody -> response.result} } + override suspend fun getDetailNews(postId: Int): NetworkResult { + return handleApi({api.getDetailNewsApi(postId = postId)}) {response: ResponseBody -> response.result} + } + + override suspend fun postCommentNews(postId: Int, request : NewsCommentRequest): NetworkResult { + return handleApi({api.postCommentNewsApi(postId = postId, request = request)}) {response: ResponseBody -> response.result} + } + + override suspend fun postReportNews( + postId: Int, + request: ReportRequest + ): NetworkResult { + return handleApi({api.postReportNewsApi(postId = postId, request= request)}) {response: ResponseBody -> response.result} + + } + + override suspend fun postReportCommentNews( + postId: Int, + request: ReportRequest + ): NetworkResult { + return handleApi({api.postReportCommentNewsApi(commentId = postId, request= request)}) {response: ResponseBody -> response.result} + } + + override suspend fun deleteCommentNews(postId: Int): NetworkResult { + return handleApi({api.deleteCommentNewsApi(commentId = postId)}) {response: ResponseBody -> response.result} + } + + override suspend fun postLikeNews(postId: Int): NetworkResult { + return handleApi({api.postLikeNewsApi(postId = postId)}) {response: ResponseBody -> response.result} + } + + override suspend fun deleteLikeNews(postId: Int): NetworkResult { + return handleApi({api.deleteLikeNewsApi(postId = postId)}) {response: ResponseBody -> response.result} + } + + override suspend fun postScrapNews(postId: Int): NetworkResult { + return handleApi({api.postScrapNewsApi(postId = postId)}) {response: ResponseBody -> response.result} + } + + override suspend fun deleteScrapNews(postId: Int): NetworkResult { + return handleApi({api.deleteScrapNewsApi(postId = postId)}) {response: ResponseBody -> response.result} + } + } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/search/SearchRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/search/SearchRepository.kt new file mode 100644 index 00000000..221d7f45 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/repository/search/SearchRepository.kt @@ -0,0 +1,18 @@ +package com.umc.ttoklip.data.repository.search + +import com.umc.ttoklip.data.model.CommonResponse +import com.umc.ttoklip.data.model.news.MainNewsResponse +import com.umc.ttoklip.data.model.news.comment.NewsCommentRequest +import com.umc.ttoklip.data.model.news.detail.NewsDetailResponse +import com.umc.ttoklip.data.model.search.NewsSearchResponse +import com.umc.ttoklip.data.model.search.SearchModel +import com.umc.ttoklip.module.NetworkResult + +interface SearchRepository { + + suspend fun getNewsSearch(title : String, sort: String): NetworkResult> + + suspend fun getTipSearch(title : String, sort: String): NetworkResult> + + suspend fun getTownSearch(title : String, sort: String): NetworkResult> +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/search/SearchRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/search/SearchRepositoryImpl.kt new file mode 100644 index 00000000..1929c050 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/repository/search/SearchRepositoryImpl.kt @@ -0,0 +1,74 @@ +package com.umc.ttoklip.data.repository.search + +import com.umc.ttoklip.data.api.SearchApi +import com.umc.ttoklip.data.model.ResponseBody +import com.umc.ttoklip.data.model.search.NewsSearchResponse +import com.umc.ttoklip.data.model.search.SearchModel +import com.umc.ttoklip.data.model.search.TipSearchResponse +import com.umc.ttoklip.data.model.search.TownSearchResponse +import com.umc.ttoklip.module.NetworkResult +import com.umc.ttoklip.module.handleApi +import javax.inject.Inject + +class SearchRepositoryImpl @Inject constructor( + private val api: SearchApi +) : SearchRepository { + + + override suspend fun getNewsSearch( + title: String, + sort: String + ): NetworkResult> { + return handleApi({ + api.getSearchNewsApi( + title = title, + sort = sort + ) + }) { response: ResponseBody -> + response.result.newsletters.map { + it.toModel( + 1 + ) + } + } + } + + override suspend fun getTipSearch( + title: String, + sort: String + ): NetworkResult> { + return handleApi({ + api.getSearchTipApi( + title = title, + sort = sort + ) + }) { response: ResponseBody -> + response.result.honeyTips.map { + it.toModel( + 3 + ) + } + } + } + + override suspend fun getTownSearch( + title: String, + sort: String + ): NetworkResult> { + return handleApi({ + api.getSearchTownApi( + title = title, + sort = sort + ) + }) { response: ResponseBody -> + response.result.communities.map { + it.toModel( + "", + 5 + ) + } + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/di/DBModule.kt b/app/src/main/java/com/umc/ttoklip/di/DBModule.kt new file mode 100644 index 00000000..69a85625 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/di/DBModule.kt @@ -0,0 +1,29 @@ +package com.umc.ttoklip.di + +import android.content.Context +import androidx.room.Room +import com.umc.ttoklip.data.db.AppDatabase +import com.umc.ttoklip.data.db.HistoryDao +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@InstallIn(SingletonComponent::class) +@Module +object DBModule { + + @Singleton + @Provides + fun provideAppDatabase( + @ApplicationContext context: Context + ): AppDatabase = Room + .databaseBuilder(context, AppDatabase::class.java, "Ttoklip.db") + .build() + + @Singleton + @Provides + fun provideHistoryDao(appDatabase: AppDatabase): HistoryDao = appDatabase.historyDao() +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/di/NetworkModule.kt b/app/src/main/java/com/umc/ttoklip/di/NetworkModule.kt index 744561bc..361e2f48 100644 --- a/app/src/main/java/com/umc/ttoklip/di/NetworkModule.kt +++ b/app/src/main/java/com/umc/ttoklip/di/NetworkModule.kt @@ -5,6 +5,7 @@ import com.umc.ttoklip.TtoklipApplication import com.umc.ttoklip.data.api.HoneyTipApi import com.umc.ttoklip.data.api.LoginApi import com.umc.ttoklip.data.api.NewsApi +import com.umc.ttoklip.data.api.SearchApi import com.umc.ttoklip.data.api.SignupApi import com.umc.ttoklip.data.api.TestApi import dagger.Module @@ -87,6 +88,12 @@ object NetworkModule { return retrofit.buildService() } + @Provides + @Singleton + fun provideSearchApi(retrofit: Retrofit): SearchApi { + return retrofit.buildService() + } + @Provides @Singleton fun provideLoginApi(retrofit: Retrofit): LoginApi{ diff --git a/app/src/main/java/com/umc/ttoklip/di/RepositoryModule.kt b/app/src/main/java/com/umc/ttoklip/di/RepositoryModule.kt index 3d289818..234ab02c 100644 --- a/app/src/main/java/com/umc/ttoklip/di/RepositoryModule.kt +++ b/app/src/main/java/com/umc/ttoklip/di/RepositoryModule.kt @@ -2,10 +2,11 @@ package com.umc.ttoklip.di import com.umc.ttoklip.data.api.LoginApi import com.umc.ttoklip.data.api.NewsApi -import com.umc.ttoklip.data.repository.login.LoginRepository -import com.umc.ttoklip.data.repository.login.LoginRepositoryImpl +import com.umc.ttoklip.data.api.SearchApi import com.umc.ttoklip.data.repository.news.NewsRepository import com.umc.ttoklip.data.repository.news.NewsRepositoryImpl +import com.umc.ttoklip.data.repository.search.SearchRepository +import com.umc.ttoklip.data.repository.search.SearchRepositoryImpl import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -23,4 +24,9 @@ object RepositoryModule { fun providesNewsRepository(api: NewsApi): NewsRepository = NewsRepositoryImpl(api) + @Provides + @Singleton + fun providesSearchRepository(api: SearchApi): SearchRepository = + SearchRepositoryImpl(api) + } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/home/HomeFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/home/HomeFragment.kt index 170ad106..fb3f011c 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/home/HomeFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/home/HomeFragment.kt @@ -1,149 +1,155 @@ -package com.umc.ttoklip.presentation.home - -import androidx.fragment.app.viewModels -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle -import com.umc.ttoklip.R -import com.umc.ttoklip.databinding.FragmentHomeBinding -import com.umc.ttoklip.presentation.MainActivity -import com.umc.ttoklip.presentation.alarm.AlarmActivity -import com.umc.ttoklip.presentation.base.BaseFragment -import com.umc.ttoklip.presentation.home.adapter.HomeTipRVA -import com.umc.ttoklip.presentation.honeytip.adapter.HoneyTips -import com.umc.ttoklip.presentation.mypage.adapter.Transaction -import com.umc.ttoklip.presentation.mypage.adapter.TransactionAdapter -import com.umc.ttoklip.presentation.news.adapter.Dummy -import com.umc.ttoklip.presentation.news.adapter.NewsRVA -import com.umc.ttoklip.presentation.news.detail.ArticleActivity -import com.umc.ttoklip.presentation.search.SearchActivity -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch - -@AndroidEntryPoint -class HomeFragment : BaseFragment(R.layout.fragment_home) { - - private val viewModel: HomeViewModel by viewModels() - private val newsRVA by lazy { - NewsRVA(onClick = { - startActivity(ArticleActivity.newIntent(requireContext())) - } - ) - } - private val townRVA by lazy { - TransactionAdapter(requireContext()) - } - private val tipRVA by lazy { - HomeTipRVA({}) - } - - override fun initObserver() { - viewLifecycleOwner.lifecycleScope.launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.activityBus.collect { - when (it) { - HomeViewModel.ActivityEventBus.SEARCH -> { - startActivity(SearchActivity.newIntent(requireContext())) - } - - HomeViewModel.ActivityEventBus.NEWS_DETAIL -> { - (requireActivity() as MainActivity).goNews() - } - - HomeViewModel.ActivityEventBus.TIP_DETAIL -> { - (requireActivity() as MainActivity).goTip() - } - - HomeViewModel.ActivityEventBus.ALARM -> { - startActivity(AlarmActivity.newIntent(requireContext())) - } - - HomeViewModel.ActivityEventBus.GROUP_BUY_DETAIL -> { - (requireActivity() as MainActivity).goTown() - } - - else -> {} - } - } - } - } - } - - override fun initView() { - binding.vm = viewModel - binding.tipRV.adapter = tipRVA - tipRVA.submitList( - listOf( - HoneyTips( - "똑똑이", - "음식물 쓰레기 냄새 방지!!", - "집에 가끔씩이지만 나타나는 바퀴벌레, 잘못 처리하면 알깐다고도...", - "1일전", - 0 - ), - HoneyTips( - "똑똑이", - "음식물 쓰레기 냄새 방지!!", - "집에 가끔씩이지만 나타나는 바퀴벌레, 잘못 처리하면 알깐다고도...", - "1일전", - 0 - ), - HoneyTips( - "똑똑이", - "음식물 쓰레기 냄새 방지!!", - "집에 가끔씩이지만 나타나는 바퀴벌레, 잘못 처리하면 알깐다고도...", - "1일전", - 0 - ) - ) - ) - binding.newsRV.adapter = newsRVA - newsRVA.submitList( - listOf( - Dummy("1"), Dummy("2"), Dummy("3") - ) - ) - binding.groupBuyRV.adapter = townRVA - townRVA.submitList( - listOf( - Transaction( - title = "같이 햇반 대량 구매하실 분?", - date = "1일전", - ownerId = "똑똑이", - address = "서울 어딘가", - currentAmount = 13000, - targetAmount = 36000, - currentMember = 1, - targetMember = 5, - commentAmount = 4, - closureReason = null - ), - Transaction( - title = "같이 햇반 대량 구매하실 분?", - date = "1일전", - ownerId = "똑똑이", - address = "서울 어딘가", - currentAmount = 36000, - targetAmount = 36000, - currentMember = 5, - targetMember = 5, - commentAmount = 14, - closureReason = "마감" - ), - Transaction( - title = "같이 햇반 대량 구매하실 분?", - date = "1일전", - ownerId = "똑똑이", - address = "서울 어딘가", - currentAmount = 36000, - targetAmount = 36000, - currentMember = 5, - targetMember = 5, - commentAmount = 14, - closureReason = "마감" - ) - ) - ) - } - +package com.umc.ttoklip.presentation.home + +import android.content.Intent +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import com.umc.ttoklip.R +import com.umc.ttoklip.databinding.FragmentHomeBinding +import com.umc.ttoklip.presentation.MainActivity +import com.umc.ttoklip.presentation.alarm.AlarmActivity +import com.umc.ttoklip.presentation.base.BaseFragment +import com.umc.ttoklip.presentation.home.adapter.HomeTipRVA +import com.umc.ttoklip.presentation.hometown.CommunicationActivity +import com.umc.ttoklip.presentation.hometown.TogetherActivity +import com.umc.ttoklip.presentation.honeytip.adapter.HoneyTips +import com.umc.ttoklip.presentation.mypage.adapter.Transaction +import com.umc.ttoklip.presentation.mypage.adapter.TransactionAdapter +import com.umc.ttoklip.presentation.news.adapter.NewsRVA +import com.umc.ttoklip.presentation.news.detail.ArticleActivity +import com.umc.ttoklip.presentation.search.SearchActivity +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class HomeFragment : BaseFragment(R.layout.fragment_home) { + + private val viewModel: HomeViewModel by viewModels() + private val newsRVA by lazy { + NewsRVA(onClick = { + NewsRVA { news -> + startActivity(ArticleActivity.newIntent(requireContext(), news.newsletterId)) + } } + ) + } + private val townRVA by lazy { + TransactionAdapter(requireContext()) + } + private val tipRVA by lazy { + HomeTipRVA({}) + } + + override fun initObserver() { + viewLifecycleOwner.lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.activityBus.collect { + when (it) { + HomeViewModel.ActivityEventBus.SEARCH -> { + startActivity(SearchActivity.newIntent(requireContext())) + } + + HomeViewModel.ActivityEventBus.NEWS_DETAIL -> { + (requireActivity() as MainActivity).goNews() + } + + HomeViewModel.ActivityEventBus.TIP_DETAIL -> { + (requireActivity() as MainActivity).goTip() + } + + HomeViewModel.ActivityEventBus.ALARM -> { + startActivity(AlarmActivity.newIntent(requireContext())) + } + + HomeViewModel.ActivityEventBus.GROUP_BUY_DETAIL -> { + (requireActivity() as MainActivity).goTown() + } + + else -> {} + } + } + } + } + } + + override fun initView() { + binding.vm = viewModel + binding.tipRV.adapter = tipRVA + tipRVA.submitList( + listOf( + HoneyTips( + "똑똑이", + "음식물 쓰레기 냄새 방지!!", + "집에 가끔씩이지만 나타나는 바퀴벌레, 잘못 처리하면 알깐다고도...", + "1일전", + 0 + ), + HoneyTips( + "똑똑이", + "음식물 쓰레기 냄새 방지!!", + "집에 가끔씩이지만 나타나는 바퀴벌레, 잘못 처리하면 알깐다고도...", + "1일전", + 0 + ), + HoneyTips( + "똑똑이", + "음식물 쓰레기 냄새 방지!!", + "집에 가끔씩이지만 나타나는 바퀴벌레, 잘못 처리하면 알깐다고도...", + "1일전", + 0 + ) + ) + ) + binding.chatImg.setOnClickListener { + val intent = Intent(requireContext(), CommunicationActivity::class.java) + startActivity(intent) + } + binding.groupButImg.setOnClickListener { + val intent = Intent(requireContext(), TogetherActivity::class.java) + startActivity(intent) + } + binding.newsRV.adapter = newsRVA + binding.groupBuyRV.adapter = townRVA + townRVA.submitList( + listOf( + Transaction( + title = "같이 햇반 대량 구매하실 분?", + date = "1일전", + ownerId = "똑똑이", + address = "서울 어딘가", + currentAmount = 13000, + targetAmount = 36000, + currentMember = 1, + targetMember = 5, + commentAmount = 4, + closureReason = null + ), + Transaction( + title = "같이 햇반 대량 구매하실 분?", + date = "1일전", + ownerId = "똑똑이", + address = "서울 어딘가", + currentAmount = 36000, + targetAmount = 36000, + currentMember = 5, + targetMember = 5, + commentAmount = 14, + closureReason = "마감" + ), + Transaction( + title = "같이 햇반 대량 구매하실 분?", + date = "1일전", + ownerId = "똑똑이", + address = "서울 어딘가", + currentAmount = 36000, + targetAmount = 36000, + currentMember = 5, + targetMember = 5, + commentAmount = 14, + closureReason = "마감" + ) + ) + ) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationActivity.kt index 43f8ae6d..8b60529a 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationActivity.kt @@ -33,9 +33,10 @@ class ReadCommunicationActivity : binding.reportBtn.setOnClickListener { val reportDialog = ReportDialogFragment() reportDialog.setDialogClickListener(object : ReportDialogFragment.DialogClickListener { - override fun onClick(request: ReportRequest) { + override fun onClick(type: String, content: String) { } + }) reportDialog.show(supportFragmentManager, reportDialog.tag) } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherActivity.kt index b400d5dd..fdd8e0d7 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherActivity.kt @@ -34,8 +34,10 @@ class ReadTogetherActivity : binding.reportBtn.setOnClickListener { val reportDialog = ReportDialogFragment() reportDialog.setDialogClickListener(object : ReportDialogFragment.DialogClickListener { - override fun onClick(request: ReportRequest) { + override fun onClick(type: String, content: String) { + } + }) reportDialog.show(supportFragmentManager, reportDialog.tag) } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ReportDialogFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ReportDialogFragment.kt index 5da3719c..71c3d657 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ReportDialogFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ReportDialogFragment.kt @@ -36,7 +36,7 @@ class ReportDialogFragment: BaseDialogFragment(R.layout.dia dismiss() } binding.acceptBtn.setOnClickListener { - dialogClickListener.onClick(ReportRequest(binding.reasonEt.text.toString(), stringToEnum(reportType))) + dialogClickListener.onClick(content = binding.reasonEt.text.toString(), type = stringToEnum(reportType)) dismiss() } } @@ -46,7 +46,7 @@ class ReportDialogFragment: BaseDialogFragment(R.layout.dia } interface DialogClickListener{ - fun onClick(request: ReportRequest) + fun onClick(type: String, content : String) } private fun resize(dialog: Dialog, width: Float, height: Float){ diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/read/ReadHoneyTipActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/read/ReadHoneyTipActivity.kt index 2b0ad4cd..bbdb8425 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/read/ReadHoneyTipActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/read/ReadHoneyTipActivity.kt @@ -1,14 +1,11 @@ package com.umc.ttoklip.presentation.honeytip.read import android.content.Intent -import android.media.Image -import android.net.Uri import android.util.Log import android.view.MotionEvent import android.view.View import android.widget.Toast import androidx.activity.viewModels -import androidx.core.view.isVisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle @@ -27,7 +24,6 @@ import com.umc.ttoklip.presentation.honeytip.adapter.ReadImageRVA import com.umc.ttoklip.presentation.honeytip.dialog.DeleteDialogFragment import com.umc.ttoklip.presentation.honeytip.dialog.ReportDialogFragment import com.umc.ttoklip.presentation.honeytip.write.WriteHoneyTipActivity -import com.umc.ttoklip.presentation.news.adapter.Comment import com.umc.ttoklip.presentation.news.adapter.CommentRVA import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -39,7 +35,7 @@ class ReadHoneyTipActivity : private val viewModel: ReadHoneyTipViewModel by viewModels() private val commentRVA by lazy { - CommentRVA() + CommentRVA({},{_,_->}) } private val imageAdapter: ReadImageRVA by lazy { @@ -100,9 +96,6 @@ class ReadHoneyTipActivity : binding.commentRv.adapter = commentRVA commentRVA.submitList( listOf( - Comment(1, 1, "ㅎㅇ", "ㅎ"), - Comment(2, 2, "ㅎㅇ", "ㅎ"), - Comment(3, 1, "ㅎㅇ", "ㅎ") ) ) } @@ -192,9 +185,9 @@ class ReadHoneyTipActivity : binding.reportBtn.setOnClickListener { val reportDialog = ReportDialogFragment() reportDialog.setDialogClickListener(object : ReportDialogFragment.DialogClickListener { - override fun onClick(request: ReportRequest) { - Log.d("report request", request.toString()) - viewModel.reportHoneyTip(postId, request) + + override fun onClick(type: String, content: String) { + viewModel.reportHoneyTip(postId,ReportRequest( content = content, reportType = type)) } }) reportDialog.show(supportFragmentManager, reportDialog.tag) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/read/ReadQuestionActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/read/ReadQuestionActivity.kt index 38fee7d2..311cbc49 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/read/ReadQuestionActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/read/ReadQuestionActivity.kt @@ -22,10 +22,10 @@ import com.umc.ttoklip.presentation.honeytip.adapter.OnReadImageClickListener import com.umc.ttoklip.presentation.honeytip.adapter.ReadImageRVA import com.umc.ttoklip.presentation.honeytip.dialog.DeleteDialogFragment import com.umc.ttoklip.presentation.honeytip.dialog.ReportDialogFragment -import com.umc.ttoklip.presentation.news.adapter.Comment import com.umc.ttoklip.presentation.news.adapter.CommentRVA import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch +import org.w3c.dom.Comment @AndroidEntryPoint class ReadQuestionActivity : BaseActivity(R.layout.activity_read_honey_tip), @@ -33,7 +33,7 @@ class ReadQuestionActivity : BaseActivity(R.layout. private val viewModel: ReadHoneyTipViewModel by viewModels() private val commentRVA by lazy { - CommentRVA() + CommentRVA({ },{_,_->}) } private val imageAdapter: ReadImageRVA by lazy { @@ -90,9 +90,6 @@ class ReadQuestionActivity : BaseActivity(R.layout. binding.commentRv.adapter = commentRVA commentRVA.submitList( listOf( - Comment(1, 1, "ㅎㅇ", "ㅎ"), - Comment(2, 2, "ㅎㅇ", "ㅎ"), - Comment(3, 1, "ㅎㅇ", "ㅎ") ) ) } @@ -161,9 +158,11 @@ class ReadQuestionActivity : BaseActivity(R.layout. binding.reportBtn.setOnClickListener { val reportDialog = ReportDialogFragment() reportDialog.setDialogClickListener(object : ReportDialogFragment.DialogClickListener { - override fun onClick(request: ReportRequest) { - Log.d("report request", request.toString()) - viewModel.reportQuestion(postId, request) + + + override fun onClick(type: String, content: String) { + Log.d("report request", content.toString()) + viewModel.reportQuestion(postId, ReportRequest(content = content, reportType = type)) } }) reportDialog.show(supportFragmentManager, reportDialog.tag) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/ItemNewsFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/ItemNewsFragment.kt deleted file mode 100644 index e057cac5..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/ItemNewsFragment.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.umc.ttoklip.presentation.news - -import androidx.fragment.app.viewModels -import com.umc.ttoklip.R -import com.umc.ttoklip.databinding.FragmentItemNewsBinding -import com.umc.ttoklip.presentation.base.BaseFragment -import com.umc.ttoklip.presentation.news.adapter.Dummy -import com.umc.ttoklip.presentation.news.adapter.NewsRVA -import com.umc.ttoklip.presentation.news.detail.ArticleActivity -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class ItemNewsFragment : BaseFragment(R.layout.fragment_item_news) { - private val viewModel: NewsViewModel by viewModels() - private val newsRVA by lazy { - NewsRVA { startActivity(ArticleActivity.newIntent(requireContext())) } - } - - override fun initObserver() { - } - - override fun initView() { - binding.vm = viewModel - binding.rv.adapter = newsRVA - newsRVA.submitList(listOf( - Dummy("1"), Dummy("2"), Dummy("3"), Dummy("4"),Dummy("1"), Dummy("2"), Dummy("3"), Dummy("4"),Dummy("1"), Dummy("2"), Dummy("3"), Dummy("4") - )) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/NewsFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/NewsFragment.kt index 0b534718..c23172e6 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/NewsFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/NewsFragment.kt @@ -1,11 +1,18 @@ package com.umc.ttoklip.presentation.news +import android.widget.Toast +import androidx.core.content.ContentProviderCompat.requireContext +import androidx.core.content.ContextCompat.startActivity import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener import com.google.android.material.tabs.TabLayoutMediator import com.umc.ttoklip.R +import com.umc.ttoklip.TtoklipApplication import com.umc.ttoklip.databinding.FragmentNewsBinding import com.umc.ttoklip.presentation.MainActivity import com.umc.ttoklip.presentation.alarm.AlarmActivity @@ -13,8 +20,10 @@ import com.umc.ttoklip.presentation.base.BaseFragment import com.umc.ttoklip.presentation.news.adapter.Dummy import com.umc.ttoklip.presentation.news.adapter.NewsCardRVA import com.umc.ttoklip.presentation.news.adapter.NewsTabAdapter +import com.umc.ttoklip.presentation.news.detail.ArticleActivity import com.umc.ttoklip.presentation.search.SearchActivity import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch @AndroidEntryPoint @@ -23,28 +32,34 @@ class NewsFragment : BaseFragment(R.layout.fragment_news) { private val viewModel: NewsViewModel by viewModels() private val vpRVA by lazy { - NewsCardRVA() + NewsCardRVA { news -> + startActivity(ArticleActivity.newIntent(requireContext(), news.newsletterId)) + } } + private val vpFA by lazy { - NewsTabAdapter(this) + NewsTabAdapter(childFragmentManager, lifecycle) } - lateinit var bindingV : FragmentNewsBinding override fun initObserver() { + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.randomNews.collect { + vpRVA.submitList(it) + } + } + } } override fun initView() { + binding.vm = viewModel viewModel.getMainNews() - bindingV =binding binding.vp.adapter = vpRVA binding.indicator.attachTo(binding.vp) - vpRVA.submitList( - listOf( - Dummy("1"), Dummy("2"), Dummy("3"), Dummy("4") - ) - ) + binding.vp2.adapter = vpFA TabLayoutMediator(binding.tabLayout, binding.vp2) { tab, position -> tab.text = tabTitleArray[position] @@ -84,7 +99,7 @@ class NewsFragment : BaseFragment(R.layout.fragment_news) { val tabTitleArray = arrayOf( "집안일", "레시피", - "안전한 생활", + "안전한생활", "복지·정책", ) } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/NewsViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/NewsViewModel.kt index 995eed05..d02dc0fd 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/NewsViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/NewsViewModel.kt @@ -1,10 +1,17 @@ package com.umc.ttoklip.presentation.news +import com.umc.ttoklip.data.model.news.News +import com.umc.ttoklip.presentation.news.adapter.NewsCard +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow interface NewsViewModel { val isExpanded : StateFlow - + val houseWorkList : StateFlow> + val recipeList : StateFlow> + val safeLivingList : StateFlow> + val welfarePolicyList : StateFlow> + val randomNews: StateFlow> fun expandedAppBar() fun collapsedAppBar() diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/NewsViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/NewsViewModelImpl.kt index 861a7c3d..4633b33a 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/NewsViewModelImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/NewsViewModelImpl.kt @@ -1,15 +1,20 @@ package com.umc.ttoklip.presentation.news +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.news.News import com.umc.ttoklip.data.repository.news.NewsRepository +import com.umc.ttoklip.module.onException import com.umc.ttoklip.module.onFail import com.umc.ttoklip.module.onSuccess +import com.umc.ttoklip.presentation.news.adapter.NewsCard import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch +import java.util.Random import javax.inject.Inject @HiltViewModel @@ -21,6 +26,30 @@ class NewsViewModelImpl @Inject constructor( override val isExpanded: StateFlow get() = _isExpanded + private val _houseWorkList = MutableStateFlow>(listOf()) + override val houseWorkList: StateFlow> + get() = _houseWorkList + + private val _recipeList = MutableStateFlow>(listOf()) + + override val recipeList: StateFlow> + get() = _recipeList + + private val _safeLivingList = MutableStateFlow>(listOf()) + + override val safeLivingList: StateFlow> + get() = _safeLivingList + + private val _welfarePolicyList = MutableStateFlow>(listOf()) + + override val welfarePolicyList: StateFlow> + get() = _welfarePolicyList + + private val _randomNews = MutableStateFlow(listOf()) + override val randomNews: StateFlow> + get() = _randomNews + + override fun expandedAppBar() { viewModelScope.launch { _isExpanded.emit(true) @@ -35,11 +64,29 @@ class NewsViewModelImpl @Inject constructor( override fun getMainNews() { viewModelScope.launch(Dispatchers.IO) { - newsRepository.getNewsMain() - .onSuccess { + try { + newsRepository.getNewsMain() + .onSuccess { + _houseWorkList.emit(it.categoryResponses.houseWork) + _recipeList.emit(it.categoryResponses.recipe) + _safeLivingList.emit(it.categoryResponses.safeLiving) + _welfarePolicyList.emit(it.categoryResponses.welfarePolicy) - }.onFail { + _randomNews.value = + listOf( + NewsCard("집안일", _houseWorkList.value.shuffled().take(4)), + NewsCard("레시피", _recipeList.value.shuffled().take(4)), + NewsCard("안전한생활", _safeLivingList.value.shuffled().take(4)), + NewsCard("복지•정책", _welfarePolicyList.value.shuffled().take(4)) + ) + }.onFail { + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") } } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/Comment.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/Comment.kt deleted file mode 100644 index dc3c0580..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/Comment.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.umc.ttoklip.presentation.news.adapter - -data class Comment( - val id : Int, - val isReply : Int, - val comment : String, - val user : String -) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/CommentRVA.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/CommentRVA.kt index 623a56b0..b10004f0 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/CommentRVA.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/CommentRVA.kt @@ -1,25 +1,35 @@ package com.umc.ttoklip.presentation.news.adapter +import android.util.Log import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.umc.ttoklip.TtoklipApplication +import com.umc.ttoklip.data.model.news.comment.NewsCommentResponse import com.umc.ttoklip.databinding.ItemCommentBinding import com.umc.ttoklip.databinding.ItemReplyBinding - -//댓글 1 대댓글 2 - -class CommentRVA : ListAdapter(differ) { +class CommentRVA(val replyComment: (Int) -> Unit, val ReportOrDelete: (Int, Boolean) -> Unit) : + ListAdapter(differ) { inner class ItemViewHolder( private val binding: ItemCommentBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: Comment) { + fun bind(data: NewsCommentResponse) { binding.item = data + binding.replyBtn.setOnClickListener { + replyComment(data.commentId) + } + binding.deleteBtn.setOnClickListener { + ReportOrDelete( + data.commentId, + data.writer == TtoklipApplication.prefs.getString("nickname", "") + ) + } } } @@ -27,8 +37,16 @@ class CommentRVA : ListAdapter(differ) { private val binding: ItemReplyBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: Comment) { + fun bind(data: NewsCommentResponse) { binding.item = data + + binding.deleteBtn.setOnClickListener { + Log.d("닉네임","${data.writer == TtoklipApplication.prefs.getString("nickname", "")}") + ReportOrDelete( + data.commentId, + data.writer == TtoklipApplication.prefs.getString("nickname", "") + ) + } } } @@ -37,7 +55,7 @@ class CommentRVA : ListAdapter(differ) { viewType: Int ): RecyclerView.ViewHolder { return when (viewType) { - 1 -> { + 0 -> { ItemViewHolder( ItemCommentBinding.inflate( LayoutInflater.from(parent.context), @@ -46,6 +64,7 @@ class CommentRVA : ListAdapter(differ) { ) ) } + else -> { ItemReplyViewHolder( ItemReplyBinding.inflate( @@ -60,26 +79,33 @@ class CommentRVA : ListAdapter(differ) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (getItemViewType(position)) { - 1 -> { + 0 -> { (holder as ItemViewHolder).bind(currentList[position]) } - else ->{ + + else -> { (holder as ItemReplyViewHolder).bind(currentList[position]) } } } override fun getItemViewType(position: Int): Int { - return currentList[position].isReply + return currentList[position].parentId ?: 0 } companion object { - val differ = object : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: Comment, newItem: Comment): Boolean { - return oldItem.id == newItem.id + val differ = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: NewsCommentResponse, + newItem: NewsCommentResponse + ): Boolean { + return oldItem.commentId == newItem.commentId } - override fun areContentsTheSame(oldItem: Comment, newItem: Comment): Boolean { + override fun areContentsTheSame( + oldItem: NewsCommentResponse, + newItem: NewsCommentResponse + ): Boolean { return oldItem == newItem } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsCard.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsCard.kt new file mode 100644 index 00000000..860cd56c --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsCard.kt @@ -0,0 +1,8 @@ +package com.umc.ttoklip.presentation.news.adapter + +import com.umc.ttoklip.data.model.news.News + +data class NewsCard( + val category: String, + val newsList : List +) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsCardRVA.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsCardRVA.kt index f495e1bc..219d7ae6 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsCardRVA.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsCardRVA.kt @@ -5,16 +5,29 @@ import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.umc.ttoklip.data.model.news.News import com.umc.ttoklip.databinding.ItemNewsViewPagerBinding -class NewsCardRVA : ListAdapter(differ) { +class NewsCardRVA(val onClick: (News) -> Unit) : ListAdapter(differ) { inner class ItemViewHolder( private val binding: ItemNewsViewPagerBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: Dummy) { + fun bind(data: NewsCard) { binding.item = data + binding.news1Img.setOnClickListener { + if (data.newsList.isNotEmpty()) onClick(data.newsList[0]) + } + binding.newsTitle2T.setOnClickListener { + if (data.newsList.size >=2) onClick(data.newsList[1]) + } + binding.newsTitle3T.setOnClickListener { + if (data.newsList.size >=3) onClick(data.newsList[2]) + } + binding.newsTitle4T.setOnClickListener { + if (data.newsList.size >=4) onClick(data.newsList[3]) + } } } @@ -36,12 +49,12 @@ class NewsCardRVA : ListAdapter(differ) { } companion object { - val differ = object : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: Dummy, newItem: Dummy): Boolean { - return oldItem.name == newItem.name + val differ = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: NewsCard, newItem: NewsCard): Boolean { + return oldItem == newItem } - override fun areContentsTheSame(oldItem: Dummy, newItem: Dummy): Boolean { + override fun areContentsTheSame(oldItem: NewsCard, newItem: NewsCard): Boolean { return oldItem == newItem } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsRVA.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsRVA.kt index 4670a545..c798cfb9 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsRVA.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsRVA.kt @@ -5,18 +5,19 @@ import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.umc.ttoklip.data.model.news.News import com.umc.ttoklip.databinding.ItemNewsBinding -class NewsRVA(val onClick: () -> Unit) : ListAdapter(differ) { +class NewsRVA(val onClick: (News) -> Unit) : ListAdapter(differ) { inner class ItemViewHolder( private val binding: ItemNewsBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: Dummy) { + fun bind(data: News) { binding.item = data binding.itemV.setOnClickListener { - onClick() + onClick(data) } } } @@ -39,12 +40,12 @@ class NewsRVA(val onClick: () -> Unit) : ListAdapter() { - override fun areItemsTheSame(oldItem: Dummy, newItem: Dummy): Boolean { - return oldItem.name == newItem.name + val differ = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: News, newItem: News): Boolean { + return oldItem.newsletterId == newItem.newsletterId } - override fun areContentsTheSame(oldItem: Dummy, newItem: Dummy): Boolean { + override fun areContentsTheSame(oldItem: News, newItem: News): Boolean { return oldItem == newItem } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsTabAdapter.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsTabAdapter.kt index 1732b798..809bbf92 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsTabAdapter.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/NewsTabAdapter.kt @@ -1,21 +1,35 @@ package com.umc.ttoklip.presentation.news.adapter import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.lifecycle.Lifecycle import androidx.viewpager2.adapter.FragmentStateAdapter -import com.umc.ttoklip.presentation.news.ItemNewsFragment import com.umc.ttoklip.presentation.news.NewsFragment +import com.umc.ttoklip.presentation.news.fragment.HouseWorkFragment +import com.umc.ttoklip.presentation.news.fragment.RecipeFragment +import com.umc.ttoklip.presentation.news.fragment.SafeLifeFragment +import com.umc.ttoklip.presentation.news.fragment.WelfareFragment -class NewsTabAdapter(fragmentActivity: NewsFragment) : FragmentStateAdapter(fragmentActivity) { +class NewsTabAdapter(fragmentActivity: FragmentManager, lifecycle: Lifecycle) : + FragmentStateAdapter(fragmentActivity, lifecycle) { + + private val fragmentList = mutableListOf( + HouseWorkFragment(), + RecipeFragment(), + SafeLifeFragment(), + WelfareFragment() + + ) override fun getItemCount(): Int = 4 override fun createFragment(position: Int): Fragment { - return when (position) { - 0 -> ItemNewsFragment() - 1 -> ItemNewsFragment() - 2 -> ItemNewsFragment() - 3 -> ItemNewsFragment() - else -> ItemNewsFragment() - } + + return fragmentList[position] } + + fun addItem(fragment: Fragment) { + fragmentList.add(fragment) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/PostImageRVA.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/PostImageRVA.kt new file mode 100644 index 00000000..76ba4427 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/PostImageRVA.kt @@ -0,0 +1,61 @@ +package com.umc.ttoklip.presentation.news.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.umc.ttoklip.R +import com.umc.ttoklip.data.model.news.detail.ImageUrl +import com.umc.ttoklip.databinding.ItemPostImageBinding + +class PostImageRVA( val onclick :(List)->Unit) : ListAdapter(differ) { + + inner class ItemViewHolder( + private val binding: ItemPostImageBinding + ) : RecyclerView.ViewHolder(binding.root) { + + fun bind(data: ImageUrl) { + Glide.with(itemView) + .load(data.imageUrl) + .placeholder(R.drawable.ic_logo_big) + .error(R.drawable.ic_logo_big) + .apply(RequestOptions().fitCenter()) + .into(binding.iv) + binding.root.setOnClickListener { + onclick(currentList) + } + } + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): ItemViewHolder { + return ItemViewHolder( + ItemPostImageBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + holder.bind(getItem(position)) + } + + companion object { + val differ = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: ImageUrl, newItem: ImageUrl): Boolean { + return oldItem.imageUrl == newItem.imageUrl + } + + override fun areContentsTheSame(oldItem: ImageUrl, newItem: ImageUrl): Boolean { + return oldItem == newItem + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/PostImageVPA.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/PostImageVPA.kt new file mode 100644 index 00000000..3ceef942 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/adapter/PostImageVPA.kt @@ -0,0 +1,58 @@ +package com.umc.ttoklip.presentation.news.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.umc.ttoklip.R +import com.umc.ttoklip.data.model.news.detail.ImageUrl +import com.umc.ttoklip.databinding.ItemImageVpBinding + +class PostImageVPA : ListAdapter(differ) { + + inner class ItemViewHolder( + private val binding: ItemImageVpBinding + ) : RecyclerView.ViewHolder(binding.root) { + + fun bind(data: ImageUrl) { + Glide.with(itemView) + .load(data.imageUrl) + .placeholder(R.drawable.ic_logo_big) + .error(R.drawable.ic_logo_big) + .apply(RequestOptions().fitCenter()) + .into(binding.iv) + } + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): ItemViewHolder { + return ItemViewHolder( + ItemImageVpBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + holder.bind(getItem(position)) + } + + companion object { + val differ = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: ImageUrl, newItem: ImageUrl): Boolean { + return oldItem.imageUrl == newItem.imageUrl + } + + override fun areContentsTheSame(oldItem: ImageUrl, newItem: ImageUrl): Boolean { + return oldItem == newItem + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleActivity.kt index 58b27dac..bd6a8c0a 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleActivity.kt @@ -2,14 +2,22 @@ package com.umc.ttoklip.presentation.news.detail import android.content.Context import android.content.Intent +import android.view.View +import android.widget.Toast import androidx.activity.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import com.umc.ttoklip.R +import com.umc.ttoklip.data.model.news.ReportRequest import com.umc.ttoklip.databinding.ActivityArticleBinding import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.news.adapter.Comment +import com.umc.ttoklip.presentation.honeytip.dialog.DeleteDialogFragment +import com.umc.ttoklip.presentation.honeytip.dialog.ReportDialogFragment import com.umc.ttoklip.presentation.news.adapter.CommentRVA -import com.umc.ttoklip.presentation.news.adapter.NewsCardRVA +import com.umc.ttoklip.presentation.news.adapter.PostImageRVA import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch @AndroidEntryPoint class ArticleActivity : BaseActivity(R.layout.activity_article) { @@ -17,23 +25,130 @@ class ArticleActivity : BaseActivity(R.layout.activity_a private val viewModel: ArticleViewModel by viewModels() private val commentRVA by lazy { - CommentRVA() + CommentRVA({ id -> + viewModel.replyCommentParentId.value = id + }, { id, myComment -> + if (myComment) { + val deleteDialog = DeleteDialogFragment() + deleteDialog.setDialogClickListener(object : + DeleteDialogFragment.DialogClickListener { + override fun onClick() { + viewModel.deleteComment(id, intent.getIntExtra(ARTICLE, 1)) + } + }) + deleteDialog.show(supportFragmentManager, deleteDialog.tag) + } else { + val reportDialog = ReportDialogFragment() + reportDialog.setDialogClickListener(object : + ReportDialogFragment.DialogClickListener { + override fun onClick(type: String, content: String) { + viewModel.postReportComment( + intent.getIntExtra(ARTICLE, 1), + ReportRequest(content = content, reportType = type) + ) + } + }) + reportDialog.show(supportFragmentManager, reportDialog.tag) + } + }) } + + private val imageRVA by lazy { + PostImageRVA { imageUrl -> + val intent = Intent(this, PostImageActivity::class.java) + intent.putExtra("images", imageUrl.map { it.imageUrl }.toTypedArray()) + startActivity(intent) + } + } + + private var isMenuOpen = false override fun initObserver() { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.comments.collect { + commentRVA.submitList(it) + } + } + } + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.toast.collect { + if (it.isNotEmpty()) { + Toast.makeText(baseContext, it, Toast.LENGTH_SHORT).show() + } + } + } + } + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.imageUrls.collect { + viewModel.imageUrls.collect { + imageRVA.submitList(it) + } + } + } + } + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.replyCommentParentId.collect { id -> + if (id == 0) { + binding.replyT.text = "" + } else { + binding.replyT.text = "@${id}" + } + } + } + } } override fun initView() { binding.vm = viewModel + binding.replyT.setOnClickListener { + viewModel.replyCommentParentId.value = 0 + } binding.backBtn.setOnClickListener { finish() } - binding.rv2.adapter = commentRVA - commentRVA.submitList(listOf(Comment(1,1,"ㅎㅇ","ㅎ"),Comment(2,2,"ㅎㅇ","ㅎ"),Comment(3,1,"ㅎㅇ","ㅎ"))) + binding.commentRV.adapter = commentRVA + viewModel.getDetail(intent.getIntExtra(ARTICLE, 0)) + binding.SendCardView.setOnClickListener { + viewModel.postComment(intent.getIntExtra(ARTICLE, 0)) + binding.commentEt.setText("") + viewModel.replyCommentParentId.value = 0 + } + binding.ImgRV.adapter = imageRVA + binding.dotBtn.setOnClickListener { + binding.menu.apply { + if (!isMenuOpen) { + visibility = View.VISIBLE + isMenuOpen = true + } else { + visibility = View.GONE + isMenuOpen = false + } + } + } + binding.menu.setOnClickListener { + val reportDialog = ReportDialogFragment() + reportDialog.setDialogClickListener(object : ReportDialogFragment.DialogClickListener { + + override fun onClick(type: String, content: String) { + viewModel.postReportNews( + intent.getIntExtra(ARTICLE, 1), + ReportRequest(content = content, reportType = type) + ) + } + }) + reportDialog.show(supportFragmentManager, reportDialog.tag) + } } companion object { const val ARTICLE = "article" - fun newIntent(context: Context) = - Intent(context, ArticleActivity::class.java) + fun newIntent(context: Context, id: Int) = + Intent(context, ArticleActivity::class.java).apply { + putExtra(ARTICLE, id) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleViewModel.kt index 4944666a..b3f73948 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleViewModel.kt @@ -1,4 +1,31 @@ package com.umc.ttoklip.presentation.news.detail +import com.umc.ttoklip.data.model.news.ReportRequest +import com.umc.ttoklip.data.model.news.comment.NewsCommentResponse +import com.umc.ttoklip.data.model.news.detail.ImageUrl +import com.umc.ttoklip.data.model.news.detail.NewsDetailResponse +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow + interface ArticleViewModel { + + + val newsDetail: StateFlow + val comments: StateFlow> + val imageUrls: StateFlow> + val replyCommentParentId :MutableStateFlow + val commentContent: MutableStateFlow + val toast:MutableStateFlow + val isLike :MutableStateFlow + val isScrap :MutableStateFlow + + fun getDetail(id: Int) + fun postComment(id: Int) + fun postReportNews(id : Int, request: ReportRequest) + fun postReportComment(id : Int, request: ReportRequest) + fun deleteComment(id: Int,postId :Int) + fun postLike() + fun deleteLike() + fun postScrap() + fun deleteScrap() } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleViewModelImpl.kt index d0e7cea1..4b779cc5 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleViewModelImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/detail/ArticleViewModelImpl.kt @@ -1,11 +1,253 @@ package com.umc.ttoklip.presentation.news.detail +import android.util.Log import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.news.ReportRequest +import com.umc.ttoklip.data.model.news.comment.NewsCommentRequest +import com.umc.ttoklip.data.model.news.comment.NewsCommentResponse +import com.umc.ttoklip.data.model.news.detail.ImageUrl +import com.umc.ttoklip.data.model.news.detail.NewsDetailResponse +import com.umc.ttoklip.data.repository.news.NewsRepository +import com.umc.ttoklip.module.onException +import com.umc.ttoklip.module.onFail +import com.umc.ttoklip.module.onSuccess import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class ArticleViewModelImpl@Inject constructor( +class ArticleViewModelImpl @Inject constructor( + private val newsRepository: NewsRepository +) : ViewModel(), ArticleViewModel { + + private val _newsDetail = MutableStateFlow(NewsDetailResponse()) + override val newsDetail: StateFlow + get() = _newsDetail + + private val _comments = MutableStateFlow(listOf()) + override val comments: StateFlow> + get() = _comments + + private val _imageUrls = MutableStateFlow(listOf()) + override val imageUrls: StateFlow> + get() = _imageUrls + + override val replyCommentParentId = MutableStateFlow(0) + override val commentContent = MutableStateFlow("") + + private val _toast = MutableStateFlow("") + override val toast: MutableStateFlow + get() = _toast + + private val _isLike = MutableStateFlow(false) + override val isLike: MutableStateFlow + get() = _isLike + + private val _isScrap = MutableStateFlow(false) + override val isScrap: MutableStateFlow + get() = _isScrap + + override fun getDetail(id: Int) { + viewModelScope.launch(Dispatchers.IO) { + try { + newsRepository.getDetailNews(id) + .onSuccess { + _newsDetail.emit(it) + //라이크 스크랩 상태 받을 예정 + _isScrap.emit(it.scrapedByCurrentUser) + _isLike.emit(it.likedByCurrentUser) + _comments.emit(it.commentResponses.sortedBy { comment -> + comment.parentId ?: comment.commentId + }) + _imageUrls.emit(it.imageUrlList) + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + override fun postComment(id: Int) { + viewModelScope.launch(Dispatchers.IO) { + try { + newsRepository.postCommentNews( + id, + NewsCommentRequest(commentContent.value, replyCommentParentId.value) + ).onSuccess { + getDetail(id) + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + + override fun deleteComment(id: Int, postId: Int) { + viewModelScope.launch(Dispatchers.IO) { + try { + newsRepository.deleteCommentNews( + id + ).onSuccess { + getDetail(postId) + _toast.emit("댓글을 삭제했습니다.") + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + override fun postLike() { + viewModelScope.launch(Dispatchers.IO) { + try { + newsRepository.postLikeNews( + newsDetail.value.newsletterId + ).onSuccess { + _isLike.emit(true) + _newsDetail.emit(newsDetail.value.copy().also { + it.likeCount += 1 + }) + _toast.emit("뉴스 좋아요") + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + override fun deleteLike() { + viewModelScope.launch(Dispatchers.IO) { + try { + newsRepository.deleteLikeNews( + newsDetail.value.newsletterId + ).onSuccess { + _isLike.emit(false) + _newsDetail.emit(newsDetail.value.copy().also { + it.likeCount -= 1 + }) + _toast.emit("뉴스 좋아요 취소") + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + override fun postScrap() { + viewModelScope.launch(Dispatchers.IO) { + try { + newsRepository.postScrapNews( + newsDetail.value.newsletterId + ).onSuccess { + _isScrap.emit(true) + _newsDetail.emit(newsDetail.value.copy().also { + it.scrapCount += 1 + }) + _toast.emit("뉴스 스크랩") + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + override fun deleteScrap() { + viewModelScope.launch(Dispatchers.IO) { + try { + newsRepository.deleteScrapNews( + newsDetail.value.newsletterId + ).onSuccess { + _isScrap.emit(false) + _newsDetail.emit(newsDetail.value.copy().also { + it.scrapCount -= 1 + }) + _toast.emit("뉴스 스크랩 취소") + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + override fun postReportNews(id: Int, request: ReportRequest) { + viewModelScope.launch(Dispatchers.IO) { + try { + newsRepository.postReportNews( + id, + request + ).onSuccess { + _toast.emit("게시글을 신고했습니다.") + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + override fun postReportComment(id: Int, request: ReportRequest) { + viewModelScope.launch(Dispatchers.IO) { + try { + newsRepository.postReportCommentNews( + id, + request + ).onSuccess { + _toast.emit("댓글을 신고했습니다.") + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + -): ViewModel(), ArticleViewModel { } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/detail/PostImageActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/detail/PostImageActivity.kt new file mode 100644 index 00000000..41bd16e7 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/detail/PostImageActivity.kt @@ -0,0 +1,39 @@ +package com.umc.ttoklip.presentation.news.detail + +import android.net.Uri +import androidx.viewpager2.widget.ViewPager2 +import com.umc.ttoklip.R +import com.umc.ttoklip.data.model.news.detail.ImageUrl +import com.umc.ttoklip.databinding.ActivityImageViewBinding +import com.umc.ttoklip.presentation.base.BaseActivity +import com.umc.ttoklip.presentation.honeytip.adapter.Image +import com.umc.ttoklip.presentation.honeytip.adapter.ImageRVA +import com.umc.ttoklip.presentation.honeytip.adapter.ImageVPA +import com.umc.ttoklip.presentation.news.adapter.PostImageRVA +import com.umc.ttoklip.presentation.news.adapter.PostImageVPA + +class PostImageActivity : BaseActivity(R.layout.activity_image_view) { + + override fun initView() { + val images = (intent.getStringArrayExtra("images") ?: emptyArray()).map { uriString -> + ImageUrl(uriString) + } + val adapter = PostImageVPA() + binding.vp.adapter = adapter + adapter.submitList(images) + binding.totalTv.text = images.size.toString() + binding.closeBtn.setOnClickListener { + finish() + } + + binding.vp.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + binding.currentTv.text = "${position + 1}/" + } + }) + } + + override fun initObserver() { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/HouseWorkFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/HouseWorkFragment.kt new file mode 100644 index 00000000..930dcbb1 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/HouseWorkFragment.kt @@ -0,0 +1,42 @@ +package com.umc.ttoklip.presentation.news.fragment + +import android.util.Log +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import com.umc.ttoklip.R +import com.umc.ttoklip.databinding.FragmentItemNewsBinding +import com.umc.ttoklip.presentation.base.BaseFragment +import com.umc.ttoklip.presentation.news.NewsViewModel +import com.umc.ttoklip.presentation.news.NewsViewModelImpl +import com.umc.ttoklip.presentation.news.adapter.NewsRVA +import com.umc.ttoklip.presentation.news.detail.ArticleActivity +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + + +class HouseWorkFragment() : BaseFragment(R.layout.fragment_item_news) { + private val parentViewModel: NewsViewModelImpl by viewModels( + ownerProducer = { requireParentFragment() } + ) + + private val newsRVA by lazy { + NewsRVA { news -> + startActivity(ArticleActivity.newIntent(requireContext(), news.newsletterId)) } + } + + override fun initObserver() { + viewLifecycleOwner.lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + parentViewModel.houseWorkList.collect { + newsRVA.submitList(it) + } + } + } + } + + override fun initView() { + binding.rv.adapter = newsRVA + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/RecipeFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/RecipeFragment.kt new file mode 100644 index 00000000..557bcc0a --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/RecipeFragment.kt @@ -0,0 +1,41 @@ +package com.umc.ttoklip.presentation.news.fragment + +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import com.umc.ttoklip.R +import com.umc.ttoklip.databinding.FragmentItemNewsBinding +import com.umc.ttoklip.presentation.base.BaseFragment +import com.umc.ttoklip.presentation.news.NewsViewModel +import com.umc.ttoklip.presentation.news.NewsViewModelImpl +import com.umc.ttoklip.presentation.news.adapter.NewsRVA +import com.umc.ttoklip.presentation.news.detail.ArticleActivity +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class RecipeFragment() : BaseFragment(R.layout.fragment_item_news) { + private val parentViewModel: NewsViewModelImpl by viewModels( + ownerProducer = { requireParentFragment() } + ) + private val newsRVA by lazy { + NewsRVA { news -> + startActivity(ArticleActivity.newIntent(requireContext(), news.newsletterId)) + } + } + + override fun initObserver() { + viewLifecycleOwner.lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + parentViewModel.recipeList.collect { + newsRVA.submitList(it) + } + } + } + } + + override fun initView() { + binding.rv.adapter = newsRVA + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/SafeLifeFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/SafeLifeFragment.kt new file mode 100644 index 00000000..392ff805 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/SafeLifeFragment.kt @@ -0,0 +1,42 @@ +package com.umc.ttoklip.presentation.news.fragment + +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import com.umc.ttoklip.R +import com.umc.ttoklip.databinding.FragmentItemNewsBinding +import com.umc.ttoklip.presentation.base.BaseFragment +import com.umc.ttoklip.presentation.news.NewsViewModelImpl +import com.umc.ttoklip.presentation.news.adapter.NewsRVA +import com.umc.ttoklip.presentation.news.detail.ArticleActivity +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class SafeLifeFragment() : BaseFragment(R.layout.fragment_item_news) { + private val parentViewModel: NewsViewModelImpl by viewModels( + ownerProducer = { requireParentFragment() } + ) + private val newsRVA by lazy { + NewsRVA { news -> + startActivity(ArticleActivity.newIntent(requireContext(), news.newsletterId)) + } + + } + + override fun initObserver() { + viewLifecycleOwner.lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + parentViewModel.safeLivingList.collect { + newsRVA.submitList(it) + } + } + + } + } + + override fun initView() { + binding.rv.adapter = newsRVA + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/WelfareFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/WelfareFragment.kt new file mode 100644 index 00000000..615633d0 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/news/fragment/WelfareFragment.kt @@ -0,0 +1,43 @@ +package com.umc.ttoklip.presentation.news.fragment + +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import com.umc.ttoklip.R +import com.umc.ttoklip.databinding.FragmentItemNewsBinding +import com.umc.ttoklip.presentation.base.BaseFragment +import com.umc.ttoklip.presentation.news.NewsViewModel +import com.umc.ttoklip.presentation.news.NewsViewModelImpl +import com.umc.ttoklip.presentation.news.adapter.NewsRVA +import com.umc.ttoklip.presentation.news.detail.ArticleActivity +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class WelfareFragment() : BaseFragment(R.layout.fragment_item_news) { + private val parentViewModel: NewsViewModelImpl by viewModels( + ownerProducer = { requireParentFragment() } + ) + private val newsRVA by lazy { + NewsRVA { news -> + startActivity(ArticleActivity.newIntent(requireContext(), news.newsletterId)) + } + } + + + override fun initObserver() { + viewLifecycleOwner.lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + parentViewModel.welfarePolicyList.collect { + newsRVA.submitList(it) + } + } + + } + } + + override fun initView() { + binding.rv.adapter = newsRVA + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/search/SearchActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/search/SearchActivity.kt index f343582f..b22cf658 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/search/SearchActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/search/SearchActivity.kt @@ -4,7 +4,6 @@ import android.content.Context import android.content.Intent import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager -import android.widget.EditText import androidx.activity.viewModels import androidx.core.widget.addTextChangedListener import androidx.lifecycle.Lifecycle @@ -17,8 +16,7 @@ import com.google.android.flexbox.FlexboxLayoutManager import com.umc.ttoklip.R import com.umc.ttoklip.databinding.ActivitySearchBinding import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.news.adapter.Dummy -import com.umc.ttoklip.presentation.search.adapter.HistoryModel +import com.umc.ttoklip.presentation.news.detail.ArticleActivity import com.umc.ttoklip.presentation.search.adapter.HistoryRVA import com.umc.ttoklip.presentation.search.adapter.SearchRVA import com.umc.ttoklip.presentation.search.dialog.BottomDialogSearchFragment @@ -31,11 +29,25 @@ class SearchActivity : BaseActivity(R.layout.activity_sea private val viewModel: SearchViewModel by viewModels() private val historyRVA by lazy { - HistoryRVA() + HistoryRVA{ title -> + binding.appBarTitleT.setText(title) + viewModel.clickHistory(title) + } } private val searchRVA by lazy { - SearchRVA({}) + SearchRVA { category, id -> + when (category) { + 1 -> { + startActivity(ArticleActivity.newIntent(this, id)) + } + 2 -> {} + 3 -> {} + 4 -> {} + 5 -> {} + else -> {} + } + } } override fun initView() { @@ -43,6 +55,11 @@ class SearchActivity : BaseActivity(R.layout.activity_sea binding.backBtn.setOnClickListener { finish() } + viewModel.getAllHistory() + + binding.deleteBtn.setOnClickListener { + viewModel.deleteAllHistory() + } //flexLayout -> RV 연동 val flexboxLayoutManager = FlexboxLayoutManager(this).apply { @@ -73,33 +90,26 @@ class SearchActivity : BaseActivity(R.layout.activity_sea } binding.searchBtn.setOnClickListener { - if (!binding.appBarTitleT.text.isNullOrEmpty()) + if (!binding.appBarTitleT.text.isNullOrEmpty()) { viewModel.clickSearchAfter() + } if (!viewModel.searchAfter.value) { binding.appBarTitleT.setText("") } } binding.searchRV.adapter = searchRVA - searchRVA.submitList( - listOf(Dummy(""), Dummy(""), Dummy("")) - ) - - historyRVA.submitList( - listOf( - HistoryModel("keepGoingBro"), - HistoryModel("keepGoingBro"), - HistoryModel("keep"), - HistoryModel("Going"), - HistoryModel("Bro"), - HistoryModel("haha"), - HistoryModel("굿"), - HistoryModel("하하"), - ) - ) } override fun initObserver() { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.historyList.collect { + historyRVA.submitList(it) + } + } + } + lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.showDialog.collect { @@ -195,14 +205,6 @@ class SearchActivity : BaseActivity(R.layout.activity_sea } 4 -> { - if (viewModel.filterBoard.value == 1) { - binding.categoryFilterT.text = "복지•정책" - } else { - binding.categoryFilterT.text = "사기" - } - } - - 5 -> { if (viewModel.filterBoard.value == 1) { binding.categoryFilterT.text = "복지•정책" } else { @@ -232,6 +234,14 @@ class SearchActivity : BaseActivity(R.layout.activity_sea } } } + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.searchList.collect { + searchRVA.submitList(it) + } + } + } } companion object { diff --git a/app/src/main/java/com/umc/ttoklip/presentation/search/SearchViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/search/SearchViewModel.kt index 212bcf51..34b1bfbe 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/search/SearchViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/search/SearchViewModel.kt @@ -1,5 +1,7 @@ package com.umc.ttoklip.presentation.search +import com.umc.ttoklip.data.db.HistoryEntity +import com.umc.ttoklip.data.model.search.SearchModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow @@ -11,10 +13,15 @@ interface SearchViewModel { val filterBoard : StateFlow val filterCategory: StateFlow val showDialog : SharedFlow + val searchList : StateFlow> + val historyList : StateFlow> fun goSearchAfter() fun goSearchBefore() fun clickSearchAfter() fun clickFilter() + fun clickHistory(title: String) + fun getAllHistory() + fun deleteAllHistory() fun filter(sort: Int, board: Int, category:Int) } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/search/SearchViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/search/SearchViewModelImpl.kt index 405a446a..7e22859e 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/search/SearchViewModelImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/search/SearchViewModelImpl.kt @@ -1,7 +1,16 @@ package com.umc.ttoklip.presentation.search +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.db.HistoryDao +import com.umc.ttoklip.data.db.HistoryEntity +import com.umc.ttoklip.data.model.search.SearchModel +import com.umc.ttoklip.data.repository.search.SearchRepository +import com.umc.ttoklip.data.repository.search.SearchRepositoryImpl +import com.umc.ttoklip.module.onException +import com.umc.ttoklip.module.onFail +import com.umc.ttoklip.module.onSuccess import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -9,10 +18,14 @@ import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch +import javax.annotation.meta.When import javax.inject.Inject @HiltViewModel -class SearchViewModelImpl @Inject constructor() : ViewModel(), SearchViewModel { +class SearchViewModelImpl @Inject constructor( + private val historyDao: HistoryDao, + private val searchRepository: SearchRepository +) : ViewModel(), SearchViewModel { override val searchText: MutableStateFlow = MutableStateFlow("") private val _searchAfter = MutableStateFlow(false) @@ -31,10 +44,35 @@ class SearchViewModelImpl @Inject constructor() : ViewModel(), SearchViewModel { get() = _filterCategory override val showDialog: SharedFlow get() = _showDialog + private val _searchList = MutableStateFlow(listOf()) + override val searchList: StateFlow> + get() = _searchList + private val _historyList = MutableStateFlow(listOf()) + override val historyList: StateFlow> + get() = _historyList + + private val fSearchList = MutableStateFlow(mutableListOf()) override fun goSearchAfter() { viewModelScope.launch { _searchAfter.emit(true) + try { + searchRepository.getNewsSearch(title = searchText.value, sort = "latest").onSuccess { + _searchList.emit(it) + fSearchList.emit(it.toMutableList()) + addHistory() + searchTip() + searchTown() + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } } @@ -48,6 +86,7 @@ class SearchViewModelImpl @Inject constructor() : ViewModel(), SearchViewModel { viewModelScope.launch { if (!searchAfter.value) { _searchAfter.emit(true) + goSearchAfter() } else { _searchAfter.emit(false) } @@ -60,12 +99,272 @@ class SearchViewModelImpl @Inject constructor() : ViewModel(), SearchViewModel { } } + override fun clickHistory(title: String) { + viewModelScope.launch { + _searchAfter.emit(true) + try { + searchRepository.getNewsSearch(title = title, sort = "latest").onSuccess { + _searchList.emit(it) + fSearchList.emit(it.toMutableList()) + searchTip() + searchTown() + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + + } + } override fun filter(sort: Int, board: Int, category: Int) { viewModelScope.launch { _filterSort.value = sort _filterBoard.value = board _filterCategory.value = category + filterCategory(filterSort.value, filterBoard.value, filterCategory.value) + } + } + + private fun searchTip() { + viewModelScope.launch { + try { + searchRepository.getTipSearch(title = searchText.value, sort = "latest").onSuccess { + _searchList.emit(searchList.value + it) + fSearchList.emit((fSearchList.value + it.toMutableList()) as MutableList) + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + private fun searchTown() { + viewModelScope.launch { + try { + searchRepository.getTownSearch(title = searchText.value, sort = "latest").onSuccess { + _searchList.emit(searchList.value + it) + fSearchList.emit((fSearchList.value + it.toMutableList()) as MutableList) + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + suspend fun addHistory() { + historyDao.addHistory(HistoryEntity(historyList.value.size, searchText.value)) + viewModelScope.launch { + _historyList.emit(listOf( HistoryEntity(historyList.value.size, searchText.value)) + historyList.value) + } + } + + override fun getAllHistory() { + viewModelScope.launch { + val history = historyDao.getAll().sortedBy { it.id } + _historyList.emit(history) + } + } + + override fun deleteAllHistory(){ + viewModelScope.launch { + historyDao.deleteAll() + _historyList.emit(listOf()) + } + } + private suspend fun filterSort(sort: Int) { + when (sort) { + 1 -> { + _searchList.emit(fSearchList.value) + } + + 2 -> { + _searchList.emit(fSearchList.value.sortedBy { it.commentCount }.reversed()) + } + + 3 -> { + _searchList.emit(fSearchList.value.sortedBy { it.commentCount }.reversed()) + } + } + } + + private suspend fun filterCategory(sort: Int, board: Int, category: Int) { + val copy: MutableList = mutableListOf() + copy.addAll(fSearchList.value) + when (sort) { + 1 -> { + when (board) { + 1 -> { + when (category) { + 1 -> { + copy.removeIf { it.bigCategory != 1 || it.category != "HOUSEWORK" } + _searchList.emit(copy) + } + + 2 -> { + copy.removeIf { it.bigCategory != 1 || it.category != "RECIPE" } + _searchList.emit(copy) + } + + 3 -> { + copy.removeIf { it.bigCategory != 1 || it.category != "SAFE_LIVING" } + _searchList.emit(copy) + } + + 4 -> { + copy.removeIf { it.bigCategory != 1 || it.category != "WELFARE_POLICY" } + _searchList.emit(copy) + } + + else -> { + copy.removeIf { it.bigCategory != 1 } + _searchList.emit(copy) + } + } + } + + 2 -> { + _searchList.emit(listOf()) + } + + 3 -> { + when (category) { + 1 -> { + copy.removeIf { it.bigCategory != 3 || it.category != "HOUSEWORK" } + _searchList.emit(copy) + } + + 2 -> { + copy.removeIf { it.bigCategory != 3 || it.category != "RECIPE" } + _searchList.emit(copy) + } + + 3 -> { + copy.removeIf { it.bigCategory != 3 || it.category != "SAFE_LIVING" } + _searchList.emit(copy) + } + + 4 -> { + copy.removeIf { it.bigCategory != 3 || it.category != "WELFARE_POLICY" } + _searchList.emit(copy) + } + + else -> { + copy.removeIf { it.bigCategory != 3 } + _searchList.emit(copy) + } + } + } + + 4 -> { + _searchList.emit(listOf()) + } + + 5 -> { + copy.removeIf { it.bigCategory != 5 } + _searchList.emit(copy) + } + + else -> { + _searchList.emit(copy) + } + } + } + + else -> { + + when (board) { + 1 -> { + when (category) { + 1 -> { + copy.removeIf { it.bigCategory != 1 || it.category != "HOUSEWORK" } + _searchList.emit(copy.sortedBy { it.commentCount }.reversed()) + } + + 2 -> { + copy.removeIf { it.bigCategory != 1 || it.category != "RECIPE" } + _searchList.emit(copy.sortedBy { it.commentCount }.reversed()) + } + + 3 -> { + copy.removeIf { it.bigCategory != 1 || it.category != "SAFE_LIVING" } + _searchList.emit(copy.sortedBy { it.commentCount }.reversed()) + } + + 4 -> { + copy.removeIf { it.bigCategory != 1 || it.category != "WELFARE_POLICY" } + _searchList.emit(copy.sortedBy { it.commentCount }.reversed()) + } + + else -> { + copy.removeIf { it.bigCategory != 1 } + _searchList.emit(copy.sortedBy { it.commentCount }.reversed()) + } + } + + } + + 2 -> { + _searchList.emit(listOf()) + } + + 3 -> { + when (category) { + 1 -> { + copy.removeIf { it.bigCategory != 3 || it.category != "HOUSEWORK" } + _searchList.emit(copy) + } + + 2 -> { + copy.removeIf { it.bigCategory != 3 || it.category != "RECIPE" } + _searchList.emit(copy) + } + + 3 -> { + copy.removeIf { it.bigCategory != 3 || it.category != "SAFE_LIVING" } + _searchList.emit(copy) + } + + 4 -> { + copy.removeIf { it.bigCategory != 3 || it.category != "WELFARE_POLICY" } + _searchList.emit(copy) + } + + else -> { + copy.removeIf { it.bigCategory != 3 } + _searchList.emit(copy) + } + } + } + + 4 -> { + _searchList.emit(listOf()) + } + + 5 -> { + copy.removeIf { it.bigCategory != 5 } + _searchList.emit(copy) + } + + else -> { + _searchList.emit(copy.sortedBy { it.commentCount }.reversed()) + } + } + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/HistoryModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/HistoryModel.kt deleted file mode 100644 index 2852b684..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/HistoryModel.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.umc.ttoklip.presentation.search.adapter - -data class HistoryModel( - val string: String -) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/HistoryRVA.kt b/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/HistoryRVA.kt index f700fd02..2d7c566f 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/HistoryRVA.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/HistoryRVA.kt @@ -4,17 +4,20 @@ import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.umc.ttoklip.data.db.HistoryEntity import com.umc.ttoklip.databinding.ItemSerachHistoryBinding -class HistoryRVA : - ListAdapter(diff) { +class HistoryRVA(private val onClick : (String) -> Unit): + ListAdapter(diff) { inner class DetailViewHolder( private val binding: ItemSerachHistoryBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: HistoryModel) { - - binding.historyT.text = data.string + fun bind(data: HistoryEntity) { + binding.historyT.text = data.history + binding.root.setOnClickListener { + onClick(data.history) + } } } @@ -33,17 +36,17 @@ class HistoryRVA : } companion object { - val diff = object : DiffUtil.ItemCallback() { + val diff = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: HistoryModel, - newItem: HistoryModel + oldItem: HistoryEntity, + newItem: HistoryEntity ): Boolean { - return oldItem.string == newItem.string + return oldItem.id == newItem.id } override fun areContentsTheSame( - oldItem: HistoryModel, - newItem: HistoryModel + oldItem: HistoryEntity, + newItem: HistoryEntity ): Boolean { return oldItem == newItem } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/SearchRVA.kt b/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/SearchRVA.kt index ca1ce379..11c0ee19 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/SearchRVA.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/search/adapter/SearchRVA.kt @@ -5,17 +5,32 @@ import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.umc.ttoklip.data.model.search.SearchModel import com.umc.ttoklip.databinding.ItemSearchBinding -import com.umc.ttoklip.presentation.news.adapter.Dummy -class SearchRVA(val onClick: () -> Unit) : ListAdapter(differ) { +class SearchRVA(val onClick: (Int,Int) -> Unit) : + ListAdapter(differ) { inner class ItemViewHolder( private val binding: ItemSearchBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: Dummy) { - + fun bind(data: SearchModel) { + binding.item = data + binding.commentCountTv.text = data.commentCount.toString() + binding.likeCountTv.text = data.likeCount.toString() + binding.starCountTv.text = data.likeCount.toString() + binding.boardT.text = when (data.bigCategory) { + 1 -> "뉴스레터" + 2 -> "질문해요" + 3 -> "꿀팁 공유해요" + 4 -> "함께해요" + 5 -> "소통해요" + else -> "" + } + binding.root.setOnClickListener { + onClick(data.bigCategory, data.id) + } } } @@ -37,12 +52,12 @@ class SearchRVA(val onClick: () -> Unit) : ListAdapter() { - override fun areItemsTheSame(oldItem: Dummy, newItem: Dummy): Boolean { - return oldItem.name == newItem.name + val differ = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: SearchModel, newItem: SearchModel): Boolean { + return oldItem.id == newItem.id } - override fun areContentsTheSame(oldItem: Dummy, newItem: Dummy): Boolean { + override fun areContentsTheSame(oldItem: SearchModel, newItem: SearchModel): Boolean { return oldItem == newItem } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/search/dialog/BottomDialogSearchFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/search/dialog/BottomDialogSearchFragment.kt index 14d40a3e..d6db1654 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/search/dialog/BottomDialogSearchFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/search/dialog/BottomDialogSearchFragment.kt @@ -84,7 +84,6 @@ class BottomDialogSearchFragment(private val completeClick: (List) -> Unit) R.id.category2 -> {} R.id.category3 -> {} R.id.category4 -> {} - R.id.category5 -> {} else -> {} } } @@ -109,7 +108,6 @@ class BottomDialogSearchFragment(private val completeClick: (List) -> Unit) category2.text = "레시피" category3.text = "안전한 생활" category4.text = "복지·정책" - category5.isGone = true } } @@ -120,11 +118,13 @@ class BottomDialogSearchFragment(private val completeClick: (List) -> Unit) category1.text = "집안일" category2.text = "요리" category3.text = "안전한 생활" - category4.text = "사기" - category5.text = "복지·정책" - category5.isVisible = true + category4.text = "복지·정책" } } + //1:최신 2:인기 3:댓많 + //1:뉴스 2:질문해요 3:꿀팁공유 4:함께해요 5:소통해요 + //1-1:집안일 2:레시피 3:안전한생활 4:복지정책 + //3-1:집안일 2:요리 3:안전한생활 4:사기 5:복지정책 private fun getResult() : List{ with(binding){ @@ -147,7 +147,6 @@ class BottomDialogSearchFragment(private val completeClick: (List) -> Unit) R.id.category2 -> 2 R.id.category3 -> 3 R.id.category4 -> 4 - R.id.category5 -> 5 else -> {0} } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/signup/SignupViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/signup/SignupViewModel.kt index 80e68394..e2c8c933 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/signup/SignupViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/signup/SignupViewModel.kt @@ -95,7 +95,7 @@ class SignupViewModel @Inject constructor( uprofileImage: String, uindependentYear: Int, uindependentMonth: Int - ) { + ){ _nickname.value = unick _categories.value = ucategories _profileImage.value = uprofileImage diff --git a/app/src/main/java/com/umc/ttoklip/util/BindAdapter.kt b/app/src/main/java/com/umc/ttoklip/util/BindAdapter.kt index 0b51dca3..1bd2536d 100644 --- a/app/src/main/java/com/umc/ttoklip/util/BindAdapter.kt +++ b/app/src/main/java/com/umc/ttoklip/util/BindAdapter.kt @@ -1,6 +1,9 @@ package com.umc.ttoklip.util +import android.annotation.SuppressLint import android.graphics.Typeface +import android.graphics.drawable.Drawable +import android.widget.ImageView import android.widget.TextView import androidx.annotation.StyleRes import androidx.appcompat.widget.AppCompatTextView @@ -8,6 +11,8 @@ import androidx.databinding.BindingAdapter import androidx.fragment.app.FragmentManager import androidx.lifecycle.ViewModel import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions import com.google.android.material.tabs.TabLayout import com.umc.ttoklip.presentation.news.NewsViewModel @@ -25,3 +30,18 @@ fun AppCompatTextView.setBold(isBold: Boolean) { this.setTypeface(null, Typeface.NORMAL) } } + +@SuppressLint("CheckResult") +@BindingAdapter(value = ["bind:url", "bind:baseImg"], requireAll = false) +fun ImageView.setUrlImg(imageUrl: String?, placeholder: Drawable?) { + Glide.with(this.context) + .load(imageUrl) + .placeholder(placeholder) + .error(placeholder) + .into(this) +} + +@BindingAdapter("textInt") +fun AppCompatTextView.textInt(int: Int) { + this.text = int.toString() +} \ No newline at end of file diff --git a/app/src/main/res/drawable/rectangle_corner_10_strok_1.xml b/app/src/main/res/drawable/rectangle_corner_10_strok_1.xml index 27a04bb3..229603d4 100644 --- a/app/src/main/res/drawable/rectangle_corner_10_strok_1.xml +++ b/app/src/main/res/drawable/rectangle_corner_10_strok_1.xml @@ -3,4 +3,5 @@ android:shape="rectangle"> + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_article.xml b/app/src/main/res/layout/activity_article.xml index 3e05c43b..db0f4992 100644 --- a/app/src/main/res/layout/activity_article.xml +++ b/app/src/main/res/layout/activity_article.xml @@ -1,21 +1,24 @@ + xmlns:tools="http://schemas.android.com/tools" + xmlns:bind="http://schemas.android.com/apk/res-auto"> + + - - + android:background="@color/white" + tools:context=".presentation.news.detail.NewsDetailActivity"> + + + + + + + + + + + + app:layout_constraintBottom_toBottomOf="@id/profileImg" + app:layout_constraintStart_toEndOf="@id/writer_tv" + app:layout_constraintTop_toTopOf="@id/profileImg" /> + app:layout_constraintTop_toBottomOf="@id/title_tv" /> + app:layout_constraintTop_toBottomOf="@id/link_layout" /> @@ -157,7 +197,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="6dp" - android:src="@drawable/ic_heart_off_20" + android:src="@{vm.isLike() ? @drawable/ic_heart_on_20 : @drawable/ic_heart_off_20}" app:layout_constraintBottom_toBottomOf="@id/bookmarkImg" app:layout_constraintStart_toEndOf="@id/bookmarkT" app:layout_constraintTop_toTopOf="@id/bookmarkImg" /> @@ -167,9 +207,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="2dp" - android:text="00" - android:textAppearance="@style/TextAppearance.App.12sp_400" + bind:textInt="@{vm.newsDetail.likeCount}" + android:textAppearance="@style/TextAppearance.App.8sp_400" android:textColor="@color/black" + android:textSize="12sp" app:layout_constraintBottom_toBottomOf="@id/bookmarkImg" app:layout_constraintStart_toEndOf="@id/likeImg" app:layout_constraintTop_toTopOf="@id/bookmarkImg" /> @@ -189,9 +230,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="2dp" - android:text="00" - android:textAppearance="@style/TextAppearance.App.12sp_400" + bind:textInt="@{vm.newsDetail.commentResponses.size()}" + android:textAppearance="@style/TextAppearance.App.8sp_400" android:textColor="@color/black" + android:textSize="12sp" app:layout_constraintBottom_toBottomOf="@id/bookmarkImg" app:layout_constraintStart_toEndOf="@id/commitImg" app:layout_constraintTop_toTopOf="@id/bookmarkImg" /> @@ -202,7 +244,8 @@ android:layout_height="wrap_content" android:layout_marginTop="12dp" android:background="@drawable/rectangle_corner_4" - android:backgroundTint="@color/gray20" + android:onClick="@{()-> vm.isScrap ? vm.deleteScrap() : vm.postScrap() }" + android:backgroundTint="@{vm.isScrap ? @color/yellow : @color/gray20}" app:layout_constraintStart_toStartOf="@id/bookmarkImg" app:layout_constraintTop_toBottomOf="@id/bookmarkImg"> @@ -212,7 +255,7 @@ android:layout_height="16dp" android:layout_margin="4dp" android:src="@drawable/ic_bookmark_off_20" - android:tint="@color/gray60" + android:tint="@{vm.isScrap ? @color/black : @color/gray60}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -225,7 +268,7 @@ android:paddingEnd="6dp" android:text="스크랩" android:textAppearance="@style/TextAppearance.App.10sp_500" - android:textColor="@color/gray60" + android:textColor="@{vm.isScrap ? @color/black : @color/gray60}" app:layout_constraintBottom_toBottomOf="@id/scrapBtnImg" app:layout_constraintStart_toEndOf="@id/scrapBtnImg" app:layout_constraintTop_toTopOf="@id/scrapBtnImg" /> @@ -239,7 +282,8 @@ android:layout_marginStart="12dp" android:layout_marginTop="12dp" android:background="@drawable/rectangle_corner_4" - android:backgroundTint="@color/gray20" + android:onClick="@{()-> vm.isLike() ? vm.deleteLike() : vm.postLike()}" + android:backgroundTint="@{vm.isLike ? @color/yellow : @color/gray20}" app:layout_constraintStart_toEndOf="@id/scrapBtn" app:layout_constraintTop_toBottomOf="@id/bookmarkImg"> @@ -249,7 +293,7 @@ android:layout_height="16dp" android:layout_margin="4dp" android:src="@drawable/ic_heart_off_20" - android:tint="@color/gray60" + android:tint="@{vm.isLike() ? @color/black : @color/gray60}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -262,62 +306,62 @@ android:paddingEnd="6dp" android:text="좋아요" android:textAppearance="@style/TextAppearance.App.10sp_500" - android:textColor="@color/gray60" + android:textColor="@{vm.isLike ? @color/black : @color/gray60}" app:layout_constraintBottom_toBottomOf="@id/likeBtnImg" app:layout_constraintStart_toEndOf="@id/likeBtnImg" app:layout_constraintTop_toTopOf="@id/likeBtnImg" /> - - + android:background="@drawable/rectangle_corner_10_strok_1" + android:gravity="start" + android:paddingHorizontal="8dp" + android:paddingVertical="5dp" + app:layout_constraintTop_toBottomOf="@id/ImgRV"> - + - + + + + app:layout_constraintTop_toBottomOf="@id/scrapBtn" /> + app:layout_constraintStart_toStartOf="parent" /> + + + android:background="@color/white" + android:padding="24dp"> - - diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 5fd495a4..ee7343f5 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -190,6 +190,7 @@ android:layout_height="40dp" android:layout_marginStart="24dp" android:layout_marginTop="24dp" + android:onClick="@{()-> vm.clickMoreTip()}" android:src="@drawable/idea_img" app:layout_constraintEnd_toStartOf="@id/chatImg" app:layout_constraintStart_toStartOf="parent" @@ -220,6 +221,7 @@ android:layout_width="40dp" android:layout_height="40dp" android:src="@drawable/help_img" + android:onClick="@{()-> vm.clickMoreTip()}" app:layout_constraintEnd_toStartOf="@id/groupButImg" app:layout_constraintStart_toEndOf="@id/newsImg" app:layout_constraintTop_toTopOf="@+id/tipImg" /> diff --git a/app/src/main/res/layout/fragment_news.xml b/app/src/main/res/layout/fragment_news.xml index 923c1caf..7e39324a 100644 --- a/app/src/main/res/layout/fragment_news.xml +++ b/app/src/main/res/layout/fragment_news.xml @@ -76,7 +76,6 @@ + app:layout_constraintTop_toTopOf="parent" + app:layout_goneMarginTop="8dp" /> @@ -131,8 +130,8 @@ + type="com.umc.ttoklip.data.model.news.comment.NewsCommentResponse" /> + android:text="@{item.commentContent}" /> + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:bind="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> + type="com.umc.ttoklip.data.model.news.News" /> @@ -34,7 +36,7 @@ android:layout_marginTop="16dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" - android:text="뉴스 제목" + android:text="똑립 뉴스" android:textAppearance="@style/TextAppearance.App.10sp_500" android:layout_width="wrap_content" android:layout_height="wrap_content" /> @@ -56,7 +58,7 @@ app:layout_constraintStart_toStartOf="@id/newsTitleT" app:layout_constraintTop_toBottomOf="@id/newsTitleT" android:layout_marginTop="6dp" - android:text="뉴스 컨텐츠 , 뉴스 컨텐츠 , 뉴스 컨텐츠, 뉴스 컨텐츠" + android:text="@{item.title}" app:layout_constraintEnd_toStartOf="@id/newsImg" android:layout_marginEnd="24dp" android:layout_height="wrap_content" /> @@ -68,7 +70,7 @@ android:layout_width="wrap_content" android:layout_marginBottom="14dp" android:textColor="@color/gray80" - android:text="20XX.XX.XX" + android:text="@{item.writtenTime}" android:textAppearance="@style/TextAppearance.App.8sp_400" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="@id/newsTitleT" @@ -79,10 +81,12 @@ app:layout_constraintEnd_toEndOf="@id/newsContentT" app:layout_constraintBottom_toBottomOf="@id/dateT" android:textAppearance="@style/TextAppearance.App.8sp_400" - android:text="10" + android:text="0" android:textColor="@color/gray80" android:layout_width="wrap_content" - android:layout_height="wrap_content" /> + android:layout_height="wrap_content" + android:visibility="gone" + tools:visibility="visible"/> + android:layout_height="12dp" + android:visibility="gone" + tools:visibility="visible"/> diff --git a/app/src/main/res/layout/item_news_view_pager.xml b/app/src/main/res/layout/item_news_view_pager.xml index 28438b3d..b59d1f4b 100644 --- a/app/src/main/res/layout/item_news_view_pager.xml +++ b/app/src/main/res/layout/item_news_view_pager.xml @@ -1,6 +1,7 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:bind="http://schemas.android.com/tools"> @@ -8,7 +9,7 @@ + type="com.umc.ttoklip.presentation.news.adapter.NewsCard" /> @@ -30,7 +31,9 @@ android:id="@+id/news1Img" android:layout_width="0dp" android:layout_height="142dp" - android:src="@color/blue" + android:scaleType="center" + bind:url="@{item.newsList[0].mainImageUrl}" + bind:baseImg="@{@drawable/news_img}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -40,7 +43,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="6dp" - android:text="레시피" + android:text="@{item.category}" android:textAppearance="@style/TextAppearance.App.14sp_500" android:textColor="@color/orange" app:layout_constraintBottom_toTopOf="@id/newsTitle1T" @@ -54,7 +57,7 @@ android:layout_marginBottom="20dp" android:ellipsize="end" android:lines="1" - android:text="맛있는 감자뇨끼 만들기!! 맛있는 감자뇨끼 만들기!! 맛있는 감자뇨끼 만들기!!" + android:text="@{item.newsList[0].title}" android:textAppearance="@style/TextAppearance.App.18sp_700" android:textColor="@color/white" app:layout_constraintBottom_toBottomOf="@id/news1Img" @@ -70,7 +73,7 @@ android:ellipsize="end" android:lines="1" android:paddingVertical="8dp" - android:text="간단한 재료로 맛깔나게 쪽파김치 만들기" + android:text="@{item.newsList[1].title}" android:textAppearance="@style/TextAppearance.App.14sp_500" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -95,7 +98,7 @@ android:ellipsize="end" android:lines="1" android:paddingVertical="8dp" - android:text="간단한 재료로 맛깔나게 쪽파김치 만들기" + android:text="@{item.newsList[2].title}" android:textAppearance="@style/TextAppearance.App.14sp_500" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -121,7 +124,7 @@ android:ellipsize="end" android:lines="1" android:paddingVertical="8dp" - android:text="간단한 재료로 맛깔나게 쪽파김치 만들기" + android:text="@{item.newsList[3].title}" android:textAppearance="@style/TextAppearance.App.14sp_500" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/layout/item_post_image.xml b/app/src/main/res/layout/item_post_image.xml new file mode 100644 index 00000000..8ab21489 --- /dev/null +++ b/app/src/main/res/layout/item_post_image.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_reply.xml b/app/src/main/res/layout/item_reply.xml index 0ac18268..dc457f1e 100644 --- a/app/src/main/res/layout/item_reply.xml +++ b/app/src/main/res/layout/item_reply.xml @@ -6,7 +6,7 @@ + type="com.umc.ttoklip.data.model.news.comment.NewsCommentResponse" /> - - - - @@ -116,7 +104,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" - android:text="1일전" + android:text="@{item.writtenTime}" android:textAppearance="@style/TextAppearance.App.12sp_400" android:textColor="@color/gray60" app:layout_constraintStart_toStartOf="@id/cardView" diff --git a/app/src/main/res/layout/item_search.xml b/app/src/main/res/layout/item_search.xml index a0aa7944..1514ec88 100644 --- a/app/src/main/res/layout/item_search.xml +++ b/app/src/main/res/layout/item_search.xml @@ -1,144 +1,154 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 0a7c7774..f9d1a603 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,8 +1,6 @@