diff --git a/.gitignore b/.gitignore index 68b1aab3..8cb31e8d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ build captures .externalNativeBuild .cxx +google-services.json local.properties .idea constant.xml \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..ec852c25 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +![in1.png](https://raw.githubusercontent.com/ttoklip/BackEnd/main/introduce/in1.png) + +![in2.png](https://raw.githubusercontent.com/ttoklip/BackEnd/main/introduce/in2.png) + +![in3.png](https://raw.githubusercontent.com/ttoklip/BackEnd/main/introduce/in3.png) + +![in4.png](https://raw.githubusercontent.com/ttoklip/BackEnd/main/introduce/in4.png) + + +## 아키텍쳐 +hangunhee39_ttoklip_architecure + + +## 맴버 +| [한건희](https://github.com/hangunhee39) | [김규진](https://github.com/kyujin0911) | [박승연](https://github.com/40food) | [심영수](https://github.com/posite) | +|:------------------------------------------------------------------:|:------------------------------------------------------------------:|:------------------------------------------------------------------:|:---------------------------------------------------------------:| +| 24.01. ~ | 24.01. ~ | 24.01. ~ | 24.01. ~ 24.02. | diff --git a/app/build.gradle b/app/build.gradle index 2863acb6..3e20f8f3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,6 +4,7 @@ plugins { id 'kotlin-kapt' id 'com.google.dagger.hilt.android' id 'dagger.hilt.android.plugin' + id 'com.google.gms.google-services' } Properties properties = new Properties() @@ -119,6 +120,9 @@ dependencies { implementation 'androidx.navigation:navigation-fragment-ktx:2.7.6' implementation 'androidx.navigation:navigation-ui-ktx:2.7.6' + implementation platform('com.google.firebase:firebase-bom:32.7.2') + implementation 'com.google.firebase:firebase-messaging-ktx' + //flexBox(flexLayout) implementation 'com.google.android.flexbox:flexbox:3.0.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ef22e1e7..85c6e9e5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,6 +10,9 @@ + + android:exported="true" /> + + + @@ -221,6 +236,15 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/FCMApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/FCMApi.kt new file mode 100644 index 00000000..56989334 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/api/FCMApi.kt @@ -0,0 +1,15 @@ +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.fcm.FCMTokenRequest +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.PATCH + +interface FCMApi { + @PATCH("/api/v1/notification/fcm_token") + suspend fun patchFCMToken( + @Body request : FCMTokenRequest + ): Response> +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/HomeApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/HomeApi.kt index 3ed88d11..a350971c 100644 --- a/app/src/main/java/com/umc/ttoklip/data/api/HomeApi.kt +++ b/app/src/main/java/com/umc/ttoklip/data/api/HomeApi.kt @@ -2,12 +2,19 @@ package com.umc.ttoklip.data.api import com.umc.ttoklip.data.model.ResponseBody import com.umc.ttoklip.data.model.home.HomeResponse +import com.umc.ttoklip.data.model.home.NotificationResponse import retrofit2.Response import retrofit2.http.GET +import retrofit2.http.Query interface HomeApi { @GET("/api/v1/home") suspend fun getHomeMainApi(): Response> + @GET("/api/v1/notification/my-notification") + suspend fun getNotifications( + @Query("notificationCategory") category: String + ): Response> + } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/HoneyTipApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/HoneyTipApi.kt index 465d03cd..54c200dc 100644 --- a/app/src/main/java/com/umc/ttoklip/data/api/HoneyTipApi.kt +++ b/app/src/main/java/com/umc/ttoklip/data/api/HoneyTipApi.kt @@ -33,7 +33,7 @@ interface HoneyTipApi { @Part("title") title: RequestBody, @Part("content") content: RequestBody, @Part("category") category: RequestBody, - @Part images: Array, + @Part images: List, @Part("url") url: RequestBody ): Response> @@ -68,7 +68,7 @@ interface HoneyTipApi { @Part("title") title: RequestBody, @Part("content") content: RequestBody, @Part("category") category: RequestBody, - @Part images: Array, + @Part images: List, @Part("url") url: RequestBody ): Response> @@ -96,7 +96,7 @@ interface HoneyTipApi { @Part("title") title: RequestBody, @Part("content") content: RequestBody, @Part("category") category: RequestBody, - @Part images: Array + @Part images: List ): Response> @GET("/api/v1/question/post/{postId}") diff --git a/app/src/main/java/com/umc/ttoklip/data/api/KakaoApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/KakaoApi.kt index cdaf8f67..efe1a993 100644 --- a/app/src/main/java/com/umc/ttoklip/data/api/KakaoApi.kt +++ b/app/src/main/java/com/umc/ttoklip/data/api/KakaoApi.kt @@ -2,7 +2,10 @@ package com.umc.ttoklip.data.api import com.umc.ttoklip.R import com.umc.ttoklip.data.model.KakaoResponse +import com.umc.ttoklip.data.model.ResponseBody +import com.umc.ttoklip.data.model.login.LoginResponse import retrofit2.Call +import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Header import retrofit2.http.Query @@ -12,5 +15,5 @@ interface KakaoApi { fun getSearchKeyword( @Header("Authorization") key: String, @Query("query") query:String - ): Call + ): Response> } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/MyAccountRestrictApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/MyAccountRestrictApi.kt deleted file mode 100644 index abc9f5e4..00000000 --- a/app/src/main/java/com/umc/ttoklip/data/api/MyAccountRestrictApi.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.umc.ttoklip.data.api - -import com.umc.ttoklip.data.model.ResponseBody -import com.umc.ttoklip.data.model.mypage.RestrictedResponse -import retrofit2.Response -import retrofit2.http.GET - -interface MyAccountRestrictApi { - @GET("/api/v1/my-page/restricted") - suspend fun getRestrictedReason(): Response> -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/MyBlockUserApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/MyPage3Api.kt similarity index 59% rename from app/src/main/java/com/umc/ttoklip/data/api/MyBlockUserApi.kt rename to app/src/main/java/com/umc/ttoklip/data/api/MyPage3Api.kt index d867f5ca..b8762612 100644 --- a/app/src/main/java/com/umc/ttoklip/data/api/MyBlockUserApi.kt +++ b/app/src/main/java/com/umc/ttoklip/data/api/MyPage3Api.kt @@ -2,16 +2,23 @@ package com.umc.ttoklip.data.api import com.umc.ttoklip.data.model.ResponseBody import com.umc.ttoklip.data.model.mypage.MyBlockUserResponse +import com.umc.ttoklip.data.model.mypage.NoticeResponse +import com.umc.ttoklip.data.model.mypage.RestrictedResponse import retrofit2.Response import retrofit2.http.DELETE import retrofit2.http.GET import retrofit2.http.Path -interface MyBlockUserApi { +interface MyPage3Api { + @GET("/api/v1/my-page/restricted") + suspend fun getRestrictedReason(): Response> + @GET("/api/v1/my-page/blocked") suspend fun getMyBlockedUser(): Response> @DELETE("/api/v1/my-page/unblock/{targetId}") suspend fun deleteBlockUser(@Path("targetId") userId: Long): Response> + @GET("api/v1/notice") + suspend fun getNotices(): Response> } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/MyPostApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/MyPostApi.kt index 594344a6..1c6de33f 100644 --- a/app/src/main/java/com/umc/ttoklip/data/api/MyPostApi.kt +++ b/app/src/main/java/com/umc/ttoklip/data/api/MyPostApi.kt @@ -7,6 +7,7 @@ import com.umc.ttoklip.data.model.mypage.MyQuestionResponse import com.umc.ttoklip.data.model.mypage.MyTogetherResponse import retrofit2.Response import retrofit2.http.GET +import retrofit2.http.Path import retrofit2.http.Query interface MyPostApi { @@ -16,6 +17,13 @@ interface MyPostApi { @GET("/api/v1/my-page/participate-deals") suspend fun getMyTogethers(@Query("page") page: Int): Response> + @GET("/api/v1/stranger/participate-deals/{userId}") + suspend fun getStrangerDeals( + @Query("page") page: Int, + @Path("userId") userId: Int + ): Response> + + @GET("/api/v1/my-page/honeytip") suspend fun getMyHoneyTips(@Query("page") page: Int): Response> diff --git a/app/src/main/java/com/umc/ttoklip/data/api/NaverApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/NaverApi.kt new file mode 100644 index 00000000..94ae86b7 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/api/NaverApi.kt @@ -0,0 +1,13 @@ +package com.umc.ttoklip.data.api + +import com.umc.ttoklip.data.model.naver.GeocodingResponse +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Query + +interface NaverApi { + @GET("map-geocode/v2/geocode") + suspend fun fetchGeocoding( + @Query("query") query: String + ): Response +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/OtherApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/OtherApi.kt new file mode 100644 index 00000000..219905e2 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/api/OtherApi.kt @@ -0,0 +1,24 @@ +package com.umc.ttoklip.data.api + +import com.umc.ttoklip.data.model.ResponseBody +import com.umc.ttoklip.data.model.mypage.MyHoneyTipsResponse +import com.umc.ttoklip.data.model.stranger.OtherUserInfoResponse +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Path +import retrofit2.http.Query + +interface OtherApi { + + @GET("/api/v1/stranger") + suspend fun getStrangeInfo( + @Query("nickname") nickname : String, + ): Response> + + @GET("/api/v1/stranger/honeytip/{userId}") + suspend fun getStrangerTip( + @Path("userId") userId : Int, + @Query("page") page : Int, + ): Response> + +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/ReadCommsApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/ReadCommsApi.kt index 1e5c9242..ad98fc09 100644 --- a/app/src/main/java/com/umc/ttoklip/data/api/ReadCommsApi.kt +++ b/app/src/main/java/com/umc/ttoklip/data/api/ReadCommsApi.kt @@ -2,6 +2,7 @@ package com.umc.ttoklip.data.api import com.umc.ttoklip.data.model.ResponseBody import com.umc.ttoklip.data.model.StandardResponse +import com.umc.ttoklip.data.model.town.CommentResponse import com.umc.ttoklip.data.model.town.CreateCommentRequest import com.umc.ttoklip.data.model.town.DeleteCommunicationResponse import com.umc.ttoklip.data.model.town.ReportRequest @@ -31,13 +32,13 @@ interface ReadCommsApi { suspend fun createCommunicationComment( @Body body: CreateCommentRequest, @Path("postId") postId: Long - ): Response> + ): Response> //소통해요 댓글 삭제 @DELETE("/api/v1/town/comms/comment/{commentId}") suspend fun deleteCommunicationComment( @Path("commentId") commentId: Long - ): Response> + ): Response> //소통해요 스크랩 추가 @POST("/api/v1/town/comms/scrap/{postId}") @@ -73,9 +74,9 @@ interface ReadCommsApi { ): Response> //소통해요 댓글 신고 - @POST("/api/v1/town/comms/comment/report/{postId}") + @POST("/api/v1/town/comms/comment/report/{commentId}") suspend fun reportCommunicationComment( - @Body body: ReportRequest, + @Body body: com.umc.ttoklip.data.model.honeytip.request.ReportRequest, @Path("commentId") commentId: Long - ): Response> + ): Response> } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/ReadTogetherApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/ReadTogetherApi.kt index 733bb74a..d357a752 100644 --- a/app/src/main/java/com/umc/ttoklip/data/api/ReadTogetherApi.kt +++ b/app/src/main/java/com/umc/ttoklip/data/api/ReadTogetherApi.kt @@ -3,13 +3,16 @@ 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.StandardResponse +import com.umc.ttoklip.data.model.town.CommentResponse import com.umc.ttoklip.data.model.town.CreateCommentRequest +import com.umc.ttoklip.data.model.town.PatchCartStatusRequest import com.umc.ttoklip.data.model.town.ReportRequest import com.umc.ttoklip.data.model.town.ViewTogetherResponse 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 @@ -26,13 +29,13 @@ interface ReadTogetherApi { suspend fun createTogetherComment( @Body body: CreateCommentRequest, @Path("postId") postId: Long - ): Response> + ): Response> //함께해요 댓글 삭제 @DELETE("/api/v1/town/carts/comment/{commentId}") suspend fun deleteTogetherComment( @Path("commentId") commentId: Long - ): Response> + ): Response> //함께해요 글 신고 @POST("/api/v1/town/carts/report/{postId}") @@ -42,11 +45,11 @@ interface ReadTogetherApi { ): Response> //함께해요 댓글 신고 - @POST("/api/v1/town/carts/comment/report/{postId}") + @POST("/api/v1/town/carts/comment/report/{commentId}") suspend fun reportTogetherComment( @Body body: ReportRequest, @Path("commentId") commentId: Long - ): Response> + ): Response> @POST("/api/v1/town/carts/participants/{cartId}") suspend fun joinTogether( @@ -57,4 +60,15 @@ interface ReadTogetherApi { suspend fun cancelTogether( @Path("cartId") postId: Long ): Response> + + @GET("/api/v1/town/carts/participants/count/{cartId}") + suspend fun fetchParticipantsCount( + @Path("cartId") postId: Long + ): Response> + + @PATCH("/api/v1/town/carts/{postId}/status") + suspend fun patchPostStatus( + @Path("postId") postId: Long, + @Body request: PatchCartStatusRequest + ): Response> } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/StrangerApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/StrangerApi.kt deleted file mode 100644 index 91fc3249..00000000 --- a/app/src/main/java/com/umc/ttoklip/data/api/StrangerApi.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.umc.ttoklip.data.api - -import com.umc.ttoklip.data.model.ResponseBody -import com.umc.ttoklip.data.model.stranger.StrangerResponse -import retrofit2.Response -import retrofit2.http.POST -import retrofit2.http.Query - -interface StrangerApi { - @POST("/api/v1/stranger") - suspend fun getStranger(@Query("nickname") nick: String) - : Response> -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/api/WriteTogetherApi.kt b/app/src/main/java/com/umc/ttoklip/data/api/WriteTogetherApi.kt index 63e89122..a989efe7 100644 --- a/app/src/main/java/com/umc/ttoklip/data/api/WriteTogetherApi.kt +++ b/app/src/main/java/com/umc/ttoklip/data/api/WriteTogetherApi.kt @@ -1,5 +1,6 @@ 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.town.CreateTogethersResponse import com.umc.ttoklip.data.model.town.PatchTogetherResponse @@ -24,7 +25,7 @@ interface WriteTogetherApi { @Part("partyMax") party: Long, @Part images: List, @Part("itemUrls") itemUrls: List - ): Response> + ): Response> //함께해요 게시글 수정 @Multipart diff --git a/app/src/main/java/com/umc/ttoklip/data/model/fcm/FCMTokenRequest.kt b/app/src/main/java/com/umc/ttoklip/data/model/fcm/FCMTokenRequest.kt new file mode 100644 index 00000000..68c6a7a9 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/fcm/FCMTokenRequest.kt @@ -0,0 +1,5 @@ +package com.umc.ttoklip.data.model.fcm + +data class FCMTokenRequest( + val fcmToken : String +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/home/NotificationItem.kt b/app/src/main/java/com/umc/ttoklip/data/model/home/NotificationItem.kt new file mode 100644 index 00000000..9c841963 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/home/NotificationItem.kt @@ -0,0 +1,10 @@ +package com.umc.ttoklip.data.model.home + +data class NotificationItem( + val noticeSuccess: Boolean, + val notificationId: Int, + val targetClassId: Int, + val targetClassName: String, + val text: String, + val title: String +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/home/NotificationResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/home/NotificationResponse.kt new file mode 100644 index 00000000..9bb81386 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/home/NotificationResponse.kt @@ -0,0 +1,5 @@ +package com.umc.ttoklip.data.model.home + +data class NotificationResponse ( + val responses : List +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/mypage/HoneyTip.kt b/app/src/main/java/com/umc/ttoklip/data/model/mypage/HoneyTip.kt index 02549c13..af31b16a 100644 --- a/app/src/main/java/com/umc/ttoklip/data/model/mypage/HoneyTip.kt +++ b/app/src/main/java/com/umc/ttoklip/data/model/mypage/HoneyTip.kt @@ -9,4 +9,6 @@ data class HoneyTip( val likeCount: Int, val scrapCount: Int, val commentCount: Int -) \ No newline at end of file +){ + constructor() : this("",0,"","","",0,0,0) +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/mypage/MyBlockUserResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/mypage/MyBlockUserResponse.kt index ad4084f0..ec4289dd 100644 --- a/app/src/main/java/com/umc/ttoklip/data/model/mypage/MyBlockUserResponse.kt +++ b/app/src/main/java/com/umc/ttoklip/data/model/mypage/MyBlockUserResponse.kt @@ -2,4 +2,6 @@ package com.umc.ttoklip.data.model.mypage data class MyBlockUserResponse( val blockedUsers: List -) \ No newline at end of file +){ + constructor(): this(emptyList()) +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/mypage/MyTogetherResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/mypage/MyTogetherResponse.kt index a0a438b5..86470cca 100644 --- a/app/src/main/java/com/umc/ttoklip/data/model/mypage/MyTogetherResponse.kt +++ b/app/src/main/java/com/umc/ttoklip/data/model/mypage/MyTogetherResponse.kt @@ -1,5 +1,11 @@ package com.umc.ttoklip.data.model.mypage +import com.umc.ttoklip.data.model.town.Togethers + data class MyTogetherResponse( - val participatedDeals: List + val carts: List, + val totalPage: Int, + val totalElements: Int, + val isFirst: Boolean, + val isLast: Boolean, ) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/mypage/NoticeDetail.kt b/app/src/main/java/com/umc/ttoklip/data/model/mypage/NoticeDetail.kt new file mode 100644 index 00000000..deee63c5 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/mypage/NoticeDetail.kt @@ -0,0 +1,8 @@ +package com.umc.ttoklip.data.model.mypage + +data class NoticeDetail( + val noticeId:Int, + val title:String, + val content:String, + var visibility: Boolean=false, +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/mypage/NoticeResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/mypage/NoticeResponse.kt new file mode 100644 index 00000000..210270ec --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/mypage/NoticeResponse.kt @@ -0,0 +1,5 @@ +package com.umc.ttoklip.data.model.mypage + +data class NoticeResponse( + val notices:List +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/naver/AddressElements.kt b/app/src/main/java/com/umc/ttoklip/data/model/naver/AddressElements.kt new file mode 100644 index 00000000..7fd8f470 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/naver/AddressElements.kt @@ -0,0 +1,8 @@ +package com.umc.ttoklip.data.model.naver + +data class AddressElements( + val types: List, + val longName: String, + val shortName: String, + val code: String +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/naver/Addresses.kt b/app/src/main/java/com/umc/ttoklip/data/model/naver/Addresses.kt new file mode 100644 index 00000000..1de4b90b --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/naver/Addresses.kt @@ -0,0 +1,11 @@ +package com.umc.ttoklip.data.model.naver + +data class Addresses( + val roadAddress: String, + val jibunAddress: String, + val englishAddress: String, + val addressElements: List, + val x: String, + val y: String, + val distance: Double +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/naver/GeocodingResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/naver/GeocodingResponse.kt new file mode 100644 index 00000000..63eb28cf --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/naver/GeocodingResponse.kt @@ -0,0 +1,8 @@ +package com.umc.ttoklip.data.model.naver + +data class GeocodingResponse( + val status: String, + val meta: Meta, + val addresses: Addresses, + val errorMessage: String +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/naver/Meta.kt b/app/src/main/java/com/umc/ttoklip/data/model/naver/Meta.kt new file mode 100644 index 00000000..de862535 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/naver/Meta.kt @@ -0,0 +1,7 @@ +package com.umc.ttoklip.data.model.naver + +data class Meta( + val totalCount: Int, + val page: Int, + val count: Int +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/stranger/OtherUserInfoResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/stranger/OtherUserInfoResponse.kt new file mode 100644 index 00000000..7e3c7a46 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/stranger/OtherUserInfoResponse.kt @@ -0,0 +1,12 @@ +package com.umc.ttoklip.data.model.stranger + +data class OtherUserInfoResponse( + val independentMonth: Int, + val independentYear: Int, + val nickname: String, + val profileImage: String, + val street: String?, + val userId: Int +) { + constructor() : this(0, 0, "", "", "", 0) +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/model/town/CommentResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/town/CommentResponse.kt index 8a640ce8..4eea2c24 100644 --- a/app/src/main/java/com/umc/ttoklip/data/model/town/CommentResponse.kt +++ b/app/src/main/java/com/umc/ttoklip/data/model/town/CommentResponse.kt @@ -2,8 +2,8 @@ package com.umc.ttoklip.data.model.town data class CommentResponse( val commentId: Long, - val commentContent: String?, - val parentId: Long?, + val commentContent: String, + val parentId: Long, val writer: String, val writtenTime: String ) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/town/PatchCartStatusRequest.kt b/app/src/main/java/com/umc/ttoklip/data/model/town/PatchCartStatusRequest.kt new file mode 100644 index 00000000..6d3b87d6 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/model/town/PatchCartStatusRequest.kt @@ -0,0 +1,5 @@ +package com.umc.ttoklip.data.model.town + +data class PatchCartStatusRequest( + val status: String +) diff --git a/app/src/main/java/com/umc/ttoklip/data/model/town/ViewCommunicationResponse.kt b/app/src/main/java/com/umc/ttoklip/data/model/town/ViewCommunicationResponse.kt index e1dfb2ea..a3ad2e1d 100644 --- a/app/src/main/java/com/umc/ttoklip/data/model/town/ViewCommunicationResponse.kt +++ b/app/src/main/java/com/umc/ttoklip/data/model/town/ViewCommunicationResponse.kt @@ -7,9 +7,9 @@ data class ViewCommunicationResponse( val imageUrls: List, val title: String, val writtenTime: String, - val scrapCount: Long, - val likeCount: Long, - val commentCount: Int, + var scrapCount: Long, + var likeCount: Long, + var commentCount: Int, val commentResponses: List, val likedByCurrentUser: Boolean, val scrapedByCurrentUser: Boolean diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/fcm/FCMRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/fcm/FCMRepository.kt new file mode 100644 index 00000000..16025bd0 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/repository/fcm/FCMRepository.kt @@ -0,0 +1,9 @@ +package com.umc.ttoklip.data.repository.fcm + +import com.umc.ttoklip.data.model.CommonResponse +import com.umc.ttoklip.data.model.fcm.FCMTokenRequest +import com.umc.ttoklip.module.NetworkResult + +interface FCMRepository { + suspend fun patchFCMToken(request : FCMTokenRequest) : NetworkResult +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/fcm/FCMRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/fcm/FCMRepositoryImpl.kt new file mode 100644 index 00000000..7cc9adf4 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/repository/fcm/FCMRepositoryImpl.kt @@ -0,0 +1,18 @@ +package com.umc.ttoklip.data.repository.fcm + +import com.umc.ttoklip.data.api.FCMApi +import com.umc.ttoklip.data.model.CommonResponse +import com.umc.ttoklip.data.model.ResponseBody +import com.umc.ttoklip.data.model.fcm.FCMTokenRequest +import com.umc.ttoklip.module.NetworkResult +import com.umc.ttoklip.module.handleApi +import javax.inject.Inject + +class FCMRepositoryImpl @Inject constructor( + private val api : FCMApi +) : FCMRepository { + + override suspend fun patchFCMToken(request : FCMTokenRequest): NetworkResult { + return handleApi({api.patchFCMToken(request)}) {response: ResponseBody -> response.result} + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/home/HomeRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/home/HomeRepository.kt index 49bcf096..56a931d6 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/home/HomeRepository.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/home/HomeRepository.kt @@ -1,9 +1,12 @@ package com.umc.ttoklip.data.repository.home import com.umc.ttoklip.data.model.home.HomeResponse +import com.umc.ttoklip.data.model.home.NotificationResponse import com.umc.ttoklip.module.NetworkResult interface HomeRepository { suspend fun getHomeMain(): NetworkResult + + suspend fun getNotifications(category: String) : NetworkResult } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/home/HomeRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/home/HomeRepositoryImpl.kt index 970531bc..a23230be 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/home/HomeRepositoryImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/home/HomeRepositoryImpl.kt @@ -1,14 +1,9 @@ package com.umc.ttoklip.data.repository.home import com.umc.ttoklip.data.api.HomeApi -import com.umc.ttoklip.data.api.SearchApi import com.umc.ttoklip.data.model.ResponseBody import com.umc.ttoklip.data.model.home.HomeResponse -import com.umc.ttoklip.data.model.news.MainNewsResponse -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.data.model.home.NotificationResponse import com.umc.ttoklip.module.NetworkResult import com.umc.ttoklip.module.handleApi import javax.inject.Inject @@ -21,4 +16,9 @@ class HomeRepositoryImpl @Inject constructor( override suspend fun getHomeMain(): NetworkResult { return handleApi({api.getHomeMainApi()}) {response: ResponseBody -> response.result} } + + override suspend fun getNotifications(category: String): NetworkResult { + return handleApi({api.getNotifications(category = category)}) {response: ResponseBody -> response.result} + + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/honeytip/HoneyTipRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/honeytip/HoneyTipRepository.kt index 80dc3ee1..4bc980e1 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/honeytip/HoneyTipRepository.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/honeytip/HoneyTipRepository.kt @@ -31,7 +31,7 @@ interface HoneyTipRepository { title: RequestBody, content: RequestBody, category: RequestBody, - images: Array, + images: List, url: RequestBody ): NetworkResult @@ -44,7 +44,7 @@ interface HoneyTipRepository { title: RequestBody, content: RequestBody, category: RequestBody, - images: Array, + images: List, url: RequestBody ): NetworkResult @@ -73,7 +73,7 @@ interface HoneyTipRepository { title: RequestBody, content: RequestBody, category: RequestBody, - images: Array + images: List ): NetworkResult suspend fun inquireQuestion(questionId: Int): NetworkResult diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/honeytip/HoneyTipRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/honeytip/HoneyTipRepositoryImpl.kt index 0a9ef909..183b50a6 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/honeytip/HoneyTipRepositoryImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/honeytip/HoneyTipRepositoryImpl.kt @@ -44,7 +44,7 @@ class HoneyTipRepositoryImpl @Inject constructor( title: RequestBody, content: RequestBody, category: RequestBody, - images: Array, + images: List, uri: RequestBody ): NetworkResult { return handleApi({ @@ -65,7 +65,7 @@ class HoneyTipRepositoryImpl @Inject constructor( title: RequestBody, content: RequestBody, category: RequestBody, - images: Array, + images: List, url: RequestBody ): NetworkResult { return handleApi({ api.patchHoneyTip(honeyTipId, title, content, category, images, url) }) @@ -119,7 +119,7 @@ class HoneyTipRepositoryImpl @Inject constructor( title: RequestBody, content: RequestBody, category: RequestBody, - images: Array + images: List ): NetworkResult { return handleApi({ api.postNewQuestion(title, content, category, images) diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/location/DirectLocationRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/location/DirectLocationRepository.kt index c790509d..f5d6e616 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/location/DirectLocationRepository.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/location/DirectLocationRepository.kt @@ -1,8 +1,8 @@ package com.umc.ttoklip.data.repository.location import com.umc.ttoklip.data.model.KakaoResponse -import retrofit2.Call +import com.umc.ttoklip.module.NetworkResult interface DirectLocationRepository { - suspend fun getDirectAddress(address:String): Call + suspend fun getDirectAddress(address:String): NetworkResult } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/location/DirectLocationRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/location/DirectLocationRepositoryImpl.kt index fc60cd38..e03a6f27 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/location/DirectLocationRepositoryImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/location/DirectLocationRepositoryImpl.kt @@ -1,17 +1,24 @@ package com.umc.ttoklip.data.repository.location import com.umc.ttoklip.R +import com.umc.ttoklip.TtoklipApplication import com.umc.ttoklip.data.api.KakaoApi import com.umc.ttoklip.data.model.KakaoResponse +import com.umc.ttoklip.data.model.ResponseBody +import com.umc.ttoklip.data.model.login.LoginResponse +import com.umc.ttoklip.module.NetworkResult +import com.umc.ttoklip.module.handleApi import retrofit2.Call import javax.inject.Inject class DirectLocationRepositoryImpl @Inject constructor( private val api: KakaoApi ): DirectLocationRepository { + companion object{ + val api_key=TtoklipApplication.getString(R.string.kakao_api_key) + } - override suspend fun getDirectAddress(address: String): Call { - val call = api.getSearchKeyword(R.string.kakao_api_key.toString(), address) - return call + override suspend fun getDirectAddress(address: String): NetworkResult { + return handleApi({api.getSearchKeyword(api_key,address)}){response: ResponseBody ->response.result} } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyAccountRestrictRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyAccountRestrictRepository.kt deleted file mode 100644 index c3ffbd2f..00000000 --- a/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyAccountRestrictRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.umc.ttoklip.data.repository.mypage - -import com.umc.ttoklip.data.model.mypage.RestrictedResponse -import com.umc.ttoklip.module.NetworkResult - -interface MyAccountRestrictRepository { - suspend fun getRestrictedReason(): NetworkResult -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyAccountRestrictRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyAccountRestrictRepositoryImpl.kt deleted file mode 100644 index a4fba174..00000000 --- a/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyAccountRestrictRepositoryImpl.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.umc.ttoklip.data.repository.mypage - -import com.umc.ttoklip.data.api.MyAccountRestrictApi -import com.umc.ttoklip.data.model.ResponseBody -import com.umc.ttoklip.data.model.mypage.RestrictedResponse -import com.umc.ttoklip.module.NetworkResult -import com.umc.ttoklip.module.handleApi -import javax.inject.Inject - -class MyAccountRestrictRepositoryImpl @Inject constructor(private val api: MyAccountRestrictApi) : - MyAccountRestrictRepository { - override suspend fun getRestrictedReason(): NetworkResult { - return handleApi({ api.getRestrictedReason() }) { response: ResponseBody -> response.result } - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyBlockUserRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyPageRepository3.kt similarity index 51% rename from app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyBlockUserRepository.kt rename to app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyPageRepository3.kt index e7b37613..5f836d52 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyBlockUserRepository.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyPageRepository3.kt @@ -1,9 +1,14 @@ package com.umc.ttoklip.data.repository.mypage import com.umc.ttoklip.data.model.mypage.MyBlockUserResponse +import com.umc.ttoklip.data.model.mypage.NoticeResponse +import com.umc.ttoklip.data.model.mypage.RestrictedResponse import com.umc.ttoklip.module.NetworkResult -interface MyBlockUserRepository { +interface MyPageRepository3 { + suspend fun getRestrictedReason(): NetworkResult suspend fun getBlockedUser(): NetworkResult suspend fun deleteBlockUser(userId: Long): NetworkResult + + suspend fun getNotice(): NetworkResult } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyBlockUserRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyPageRepository3Impl.kt similarity index 50% rename from app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyBlockUserRepositoryImpl.kt rename to app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyPageRepository3Impl.kt index e042123e..8a2d2959 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyBlockUserRepositoryImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyPageRepository3Impl.kt @@ -1,14 +1,21 @@ package com.umc.ttoklip.data.repository.mypage -import com.umc.ttoklip.data.api.MyBlockUserApi +import com.umc.ttoklip.data.api.MyPage3Api import com.umc.ttoklip.data.model.ResponseBody import com.umc.ttoklip.data.model.mypage.MyBlockUserResponse +import com.umc.ttoklip.data.model.mypage.NoticeResponse +import com.umc.ttoklip.data.model.mypage.RestrictedResponse import com.umc.ttoklip.module.NetworkResult import com.umc.ttoklip.module.handleApi import javax.inject.Inject -class MyBlockUserRepositoryImpl @Inject constructor(private val api: MyBlockUserApi) : - MyBlockUserRepository { +class MyPageRepository3Impl @Inject constructor( + private val api: MyPage3Api +) : MyPageRepository3 { + override suspend fun getRestrictedReason(): NetworkResult { + return handleApi({ api.getRestrictedReason() }) { response: ResponseBody -> response.result } + } + override suspend fun getBlockedUser(): NetworkResult { return handleApi({ api.getMyBlockedUser() }) { response: ResponseBody -> response.result } } @@ -16,4 +23,9 @@ class MyBlockUserRepositoryImpl @Inject constructor(private val api: MyBlockUser override suspend fun deleteBlockUser(userId: Long): NetworkResult { return handleApi({ api.deleteBlockUser(userId) }) { response: ResponseBody -> response.result } } + + override suspend fun getNotice(): NetworkResult { + return handleApi({api.getNotices()}){response:ResponseBody->response.result} + } + } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyPostRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyPostRepositoryImpl.kt index 96f71e73..27b9aac1 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyPostRepositoryImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/mypage/MyPostRepositoryImpl.kt @@ -10,6 +10,7 @@ import com.umc.ttoklip.module.NetworkResult import com.umc.ttoklip.module.handleApi import javax.inject.Inject + class MyPostRepositoryImpl @Inject constructor(private val api: MyPostApi) : MyPostRepository { override suspend fun getMyQuestions(page: Int): NetworkResult { return handleApi({ api.getMyQuestions(page) }) { response: ResponseBody -> response.result } diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/naver/NaverRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/naver/NaverRepository.kt new file mode 100644 index 00000000..6fa34d3a --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/repository/naver/NaverRepository.kt @@ -0,0 +1,8 @@ +package com.umc.ttoklip.data.repository.naver + +import com.umc.ttoklip.data.model.naver.GeocodingResponse +import com.umc.ttoklip.module.NetworkResult + +interface NaverRepository { + suspend fun fetchGeocoding(query: String): NetworkResult +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/naver/NaverRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/naver/NaverRepositoryImpl.kt new file mode 100644 index 00000000..7c469299 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/repository/naver/NaverRepositoryImpl.kt @@ -0,0 +1,16 @@ +package com.umc.ttoklip.data.repository.naver + +import com.umc.ttoklip.data.api.NaverApi +import com.umc.ttoklip.data.model.naver.GeocodingResponse +import com.umc.ttoklip.module.NetworkResult +import com.umc.ttoklip.module.handleApi +import javax.inject.Inject + +class NaverRepositoryImpl @Inject constructor( + private val api: NaverApi +) : NaverRepository { + override suspend fun fetchGeocoding(query: String): NetworkResult { + return handleApi({api.fetchGeocoding(query)}) {response: GeocodingResponse -> response} + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/stranger/StrangerRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/stranger/StrangerRepository.kt index d8dc1849..9fc61a92 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/stranger/StrangerRepository.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/stranger/StrangerRepository.kt @@ -1,9 +1,13 @@ package com.umc.ttoklip.data.repository.stranger +import com.umc.ttoklip.data.model.mypage.MyHoneyTipsResponse import com.umc.ttoklip.data.model.signup.SignupResponse +import com.umc.ttoklip.data.model.stranger.OtherUserInfoResponse import com.umc.ttoklip.data.model.stranger.StrangerResponse import com.umc.ttoklip.module.NetworkResult interface StrangerRepository { - suspend fun getStranger(nick:String): NetworkResult + suspend fun getStranger(nick:String): NetworkResult + + suspend fun getStrangerTip(page : Int, id : Int) : NetworkResult } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/stranger/StrangerRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/stranger/StrangerRepositoryImpl.kt new file mode 100644 index 00000000..f495838d --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/data/repository/stranger/StrangerRepositoryImpl.kt @@ -0,0 +1,24 @@ +package com.umc.ttoklip.data.repository.stranger + +import com.umc.ttoklip.data.api.OtherApi +import com.umc.ttoklip.data.model.ResponseBody +import com.umc.ttoklip.data.model.mypage.MyHoneyTipsResponse +import com.umc.ttoklip.data.model.stranger.OtherUserInfoResponse +import com.umc.ttoklip.module.NetworkResult +import com.umc.ttoklip.module.handleApi +import javax.inject.Inject + +class StrangerRepositoryImpl @Inject constructor( + private val api : OtherApi +) : StrangerRepository { + + override suspend fun getStranger(nick: String): NetworkResult { + return handleApi({api.getStrangeInfo(nick)}) {response: ResponseBody ->response.result} + } + + override suspend fun getStrangerTip(page: Int, id: Int): NetworkResult { + return handleApi({api.getStrangerTip(id,page)}) {response: ResponseBody -> response.result} + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadCommsRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadCommsRepository.kt index bf0a1e0c..642ced6d 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadCommsRepository.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadCommsRepository.kt @@ -1,6 +1,7 @@ package com.umc.ttoklip.data.repository.town import com.umc.ttoklip.data.model.StandardResponse +import com.umc.ttoklip.data.model.town.CommentResponse import com.umc.ttoklip.data.model.town.CreateCommentRequest import com.umc.ttoklip.data.model.town.DeleteCommunicationResponse import com.umc.ttoklip.data.model.town.ReportRequest @@ -15,7 +16,7 @@ interface ReadCommsRepository { suspend fun reportComms(postId: Long, body: ReportRequest): NetworkResult suspend fun addCommsLike(postId: Long): NetworkResult suspend fun cancelCommsLike(postId: Long): NetworkResult - suspend fun createCommsComment(postId: Long, body: CreateCommentRequest): NetworkResult - suspend fun reportCommsComment(commentId: Long, body: ReportRequest): NetworkResult - suspend fun deleteCommsComment(commentId: Long): NetworkResult + suspend fun createCommsComment(postId: Long, body: CreateCommentRequest): NetworkResult + suspend fun reportCommsComment(commentId: Long, body: com.umc.ttoklip.data.model.honeytip.request.ReportRequest): NetworkResult + suspend fun deleteCommsComment(commentId: Long): NetworkResult } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadCommsRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadCommsRepositoryImpl.kt index 0d4f39bd..f322ad2a 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadCommsRepositoryImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadCommsRepositoryImpl.kt @@ -3,6 +3,7 @@ package com.umc.ttoklip.data.repository.town import com.umc.ttoklip.data.api.ReadCommsApi import com.umc.ttoklip.data.model.ResponseBody import com.umc.ttoklip.data.model.StandardResponse +import com.umc.ttoklip.data.model.town.CommentResponse import com.umc.ttoklip.data.model.town.CreateCommentRequest import com.umc.ttoklip.data.model.town.DeleteCommunicationResponse import com.umc.ttoklip.data.model.town.ReportRequest @@ -52,29 +53,29 @@ class ReadCommsRepositoryImpl @Inject constructor(private val api: ReadCommsApi) override suspend fun createCommsComment( postId: Long, body: CreateCommentRequest - ): NetworkResult { + ): NetworkResult { return handleApi({ api.createCommunicationComment( postId = postId, body = body ) - }) { response: ResponseBody -> response.result } + }) { response: ResponseBody -> response.result } } override suspend fun reportCommsComment( commentId: Long, - body: ReportRequest - ): NetworkResult { + body: com.umc.ttoklip.data.model.honeytip.request.ReportRequest + ): NetworkResult { return handleApi({ api.reportCommunicationComment( commentId = commentId, body = body ) - }) { response: ResponseBody -> response.result } + }) { response: ResponseBody -> response.result } } - override suspend fun deleteCommsComment(commentId: Long): NetworkResult { - return handleApi({ api.deleteCommunicationComment(commentId) }) { response: ResponseBody -> response.result } + override suspend fun deleteCommsComment(commentId: Long): NetworkResult { + return handleApi({ api.deleteCommunicationComment(commentId) }) { response: ResponseBody -> response.result } } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadTogetherRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadTogetherRepository.kt index 0c2a6633..345879a4 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadTogetherRepository.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadTogetherRepository.kt @@ -2,18 +2,24 @@ package com.umc.ttoklip.data.repository.town import com.umc.ttoklip.data.model.CommonResponse import com.umc.ttoklip.data.model.StandardResponse +import com.umc.ttoklip.data.model.town.CommentResponse import com.umc.ttoklip.data.model.town.CreateCommentRequest +import com.umc.ttoklip.data.model.town.PatchCartStatusRequest import com.umc.ttoklip.data.model.town.ReportRequest import com.umc.ttoklip.data.model.town.ViewTogetherResponse import com.umc.ttoklip.module.NetworkResult interface ReadTogetherRepository { suspend fun viewTogether(postId: Long): NetworkResult - suspend fun createTogetherComment(postId: Long, body: CreateCommentRequest): NetworkResult - suspend fun deleteTogetherComment(commentId: Long): NetworkResult + suspend fun createTogetherComment(postId: Long, body: CreateCommentRequest): NetworkResult + suspend fun deleteTogetherComment(commentId: Long): NetworkResult suspend fun reportTogether(postId: Long, body: ReportRequest): NetworkResult - suspend fun reportTogetherComment(commentId: Long, body: ReportRequest): NetworkResult + suspend fun reportTogetherComment(commentId: Long, body: ReportRequest): NetworkResult suspend fun joinTogether(postId: Long): NetworkResult suspend fun cancelTogether(postId: Long): NetworkResult + + suspend fun fetchParticipantsCount(postId: Long): NetworkResult + + suspend fun patchPostStatus(postId: Long, request: PatchCartStatusRequest): NetworkResult } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadTogetherRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadTogetherRepositoryImpl.kt index c9abe96a..f23c6175 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadTogetherRepositoryImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/town/ReadTogetherRepositoryImpl.kt @@ -4,7 +4,9 @@ import com.umc.ttoklip.data.api.ReadTogetherApi import com.umc.ttoklip.data.model.CommonResponse import com.umc.ttoklip.data.model.ResponseBody import com.umc.ttoklip.data.model.StandardResponse +import com.umc.ttoklip.data.model.town.CommentResponse import com.umc.ttoklip.data.model.town.CreateCommentRequest +import com.umc.ttoklip.data.model.town.PatchCartStatusRequest import com.umc.ttoklip.data.model.town.ReportRequest import com.umc.ttoklip.data.model.town.ViewTogetherResponse import com.umc.ttoklip.module.NetworkResult @@ -20,17 +22,17 @@ class ReadTogetherRepositoryImpl @Inject constructor(private val api: ReadTogeth override suspend fun createTogetherComment( postId: Long, body: CreateCommentRequest - ): NetworkResult { + ): NetworkResult { return handleApi({ api.createTogetherComment( postId = postId, body = body ) - }) { response: ResponseBody -> response.result } + }) { response: ResponseBody -> response.result } } - override suspend fun deleteTogetherComment(commentId: Long): NetworkResult { - return handleApi({ api.deleteTogetherComment(commentId) }) { response: ResponseBody -> response.result } + override suspend fun deleteTogetherComment(commentId: Long): NetworkResult { + return handleApi({ api.deleteTogetherComment(commentId) }) { response: ResponseBody -> response.result } } override suspend fun reportTogether( @@ -48,13 +50,13 @@ class ReadTogetherRepositoryImpl @Inject constructor(private val api: ReadTogeth override suspend fun reportTogetherComment( commentId: Long, body: ReportRequest - ): NetworkResult { + ): NetworkResult { return handleApi({ api.reportTogetherComment( commentId = commentId, body = body ) - }) { response: ResponseBody -> response.result } + }) { response: ResponseBody -> response.result } } override suspend fun joinTogether(postId: Long): NetworkResult { @@ -64,4 +66,12 @@ class ReadTogetherRepositoryImpl @Inject constructor(private val api: ReadTogeth override suspend fun cancelTogether(postId: Long): NetworkResult { return handleApi({ api.cancelTogether(postId) }) { response: ResponseBody -> response.result } } + + override suspend fun fetchParticipantsCount(postId: Long): NetworkResult { + return handleApi({api.fetchParticipantsCount(postId)}) {response: ResponseBody -> response.result} + } + + override suspend fun patchPostStatus(postId: Long, request: PatchCartStatusRequest): NetworkResult { + return handleApi({api.patchPostStatus(postId, request)}) {response: ResponseBody -> response.result} + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/town/WriteTogetherRepository.kt b/app/src/main/java/com/umc/ttoklip/data/repository/town/WriteTogetherRepository.kt index d5c01f9c..2b284f0b 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/town/WriteTogetherRepository.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/town/WriteTogetherRepository.kt @@ -1,12 +1,13 @@ package com.umc.ttoklip.data.repository.town +import com.umc.ttoklip.data.model.CommonResponse import com.umc.ttoklip.data.model.town.CreateTogethersRequest import com.umc.ttoklip.data.model.town.CreateTogethersResponse import com.umc.ttoklip.data.model.town.PatchTogetherResponse import com.umc.ttoklip.module.NetworkResult interface WriteTogetherRepository { - suspend fun createTogether(body: CreateTogethersRequest): NetworkResult + suspend fun createTogether(body: CreateTogethersRequest): NetworkResult suspend fun patchTogether( postId: Long, body: CreateTogethersRequest diff --git a/app/src/main/java/com/umc/ttoklip/data/repository/town/WriteTogetherRepositoryImpl.kt b/app/src/main/java/com/umc/ttoklip/data/repository/town/WriteTogetherRepositoryImpl.kt index 9b846819..3a6eb019 100644 --- a/app/src/main/java/com/umc/ttoklip/data/repository/town/WriteTogetherRepositoryImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/data/repository/town/WriteTogetherRepositoryImpl.kt @@ -1,6 +1,7 @@ package com.umc.ttoklip.data.repository.town import com.umc.ttoklip.data.api.WriteTogetherApi +import com.umc.ttoklip.data.model.CommonResponse import com.umc.ttoklip.data.model.ResponseBody import com.umc.ttoklip.data.model.town.CreateTogethersRequest import com.umc.ttoklip.data.model.town.CreateTogethersResponse @@ -11,7 +12,7 @@ import javax.inject.Inject class WriteTogetherRepositoryImpl @Inject constructor(private val api: WriteTogetherApi) : WriteTogetherRepository { - override suspend fun createTogether(body: CreateTogethersRequest): NetworkResult { + override suspend fun createTogether(body: CreateTogethersRequest): NetworkResult { return handleApi({ api.createTogethers( title = body.title, @@ -23,7 +24,7 @@ class WriteTogetherRepositoryImpl @Inject constructor(private val api: WriteToge images = body.images, itemUrls = body.itemUrls ) - }) { response: ResponseBody -> response.result } + }) { response: ResponseBody -> response.result } } override suspend fun patchTogether( diff --git a/app/src/main/java/com/umc/ttoklip/di/KakaoModule.kt b/app/src/main/java/com/umc/ttoklip/di/KakaoModule.kt deleted file mode 100644 index ed5eef7b..00000000 --- a/app/src/main/java/com/umc/ttoklip/di/KakaoModule.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.umc.ttoklip.di - -import android.util.Log -import com.umc.ttoklip.R -import com.umc.ttoklip.data.api.KakaoApi -import com.umc.ttoklip.data.api.TermApi -import com.umc.ttoklip.data.model.KakaoResponse -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -object KakaoModule { - -// private val BASE_URL = R.string.kakao.toString() -// @Provides -// @Singleton -// fun kakaoApiRetrofitClient(keyword: String) { -// val retrofit = Retrofit.Builder() -// .baseUrl(BASE_URL) -// .addConverterFactory(GsonConverterFactory.create()) -// .build() -// val api = retrofit.create(KakaoApi::class.java) -// } -} \ 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 932bdb77..728d38ce 100644 --- a/app/src/main/java/com/umc/ttoklip/di/NetworkModule.kt +++ b/app/src/main/java/com/umc/ttoklip/di/NetworkModule.kt @@ -2,6 +2,8 @@ package com.umc.ttoklip.di import com.umc.ttoklip.R import com.umc.ttoklip.TtoklipApplication +import com.umc.ttoklip.TtoklipApplication.Companion.getString +import com.umc.ttoklip.data.api.FCMApi import com.umc.ttoklip.data.api.HomeApi import com.umc.ttoklip.data.api.HoneyTipApi import com.umc.ttoklip.data.api.KakaoApi @@ -10,10 +12,11 @@ import com.umc.ttoklip.data.api.MyPage2Api import com.umc.ttoklip.data.api.MyPageApi import com.umc.ttoklip.data.api.MainCommsApi import com.umc.ttoklip.data.api.MainTogethersApi -import com.umc.ttoklip.data.api.MyAccountRestrictApi -import com.umc.ttoklip.data.api.MyBlockUserApi +import com.umc.ttoklip.data.api.MyPage3Api import com.umc.ttoklip.data.api.MyPostApi +import com.umc.ttoklip.data.api.NaverApi import com.umc.ttoklip.data.api.NewsApi +import com.umc.ttoklip.data.api.OtherApi import com.umc.ttoklip.data.api.ReadCommsApi import com.umc.ttoklip.data.api.ReadTogetherApi import com.umc.ttoklip.data.api.Search2Api @@ -24,18 +27,19 @@ import com.umc.ttoklip.data.api.TestApi import com.umc.ttoklip.data.api.TownMainApi import com.umc.ttoklip.data.api.WriteCommsApi import com.umc.ttoklip.data.api.WriteTogetherApi +import com.umc.ttoklip.util.NaverInterceptor import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import okhttp3.Interceptor import okhttp3.OkHttpClient +import okhttp3.Request import okhttp3.Response import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.scalars.ScalarsConverterFactory -import retrofit2.create import java.util.concurrent.TimeUnit import javax.inject.Named import javax.inject.Singleton @@ -77,6 +81,31 @@ object NetworkModule { }.build() } + @Provides + @Singleton + @Named("NaverClient") + fun provideNaverOKHttpClient(): OkHttpClient { + val interceptor = HttpLoggingInterceptor().apply { + level = HttpLoggingInterceptor.Level.BODY + } + + val closeInterceptor = Interceptor { chain -> + val request: Request = + chain.request().newBuilder().addHeader("Connection", "close").build() + chain.proceed(request) + } + + return OkHttpClient.Builder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(10, TimeUnit.SECONDS) + .writeTimeout(5, TimeUnit.SECONDS) + .addInterceptor(NaverInterceptor()) + .addInterceptor(interceptor) + .addNetworkInterceptor(closeInterceptor) + .retryOnConnectionFailure(false) + .build() + } + @Provides @Singleton @@ -111,15 +140,28 @@ object NetworkModule { @Named("kakao") fun providesKakaoRetrofit( @Named("kakaoClient") client: OkHttpClient, - gsonConverterFactory: GsonConverterFactory ): Retrofit { return Retrofit.Builder() - .baseUrl(R.string.kakao.toString()) - .addConverterFactory(gsonConverterFactory) + .baseUrl(TtoklipApplication.getString(R.string.kakao)) + .addConverterFactory(GsonConverterFactory.create()) .client(client) .build() } + @Provides + @Singleton + @Named("naver") + fun providesNaverRetrofit( + @Named("NaverClient") client: OkHttpClient, + ): Retrofit{ + return Retrofit.Builder() + .client(client) + .baseUrl(getString(R.string. naver_url)) + .addConverterFactory(ScalarsConverterFactory.create()) + .addConverterFactory(GsonConverterFactory.create()) + .build() + } + @Provides @Singleton fun provideTestApi(retrofit: Retrofit): TestApi { @@ -196,21 +238,15 @@ object NetworkModule { fun provideMyPage2Api(retrofit: Retrofit): MyPage2Api{ return retrofit.buildService() } - @Provides - @Singleton - fun providesAccountRestrictApi(retrofit: Retrofit): MyAccountRestrictApi { - return retrofit.buildService() - } - @Provides @Singleton - fun providesMyPostApi(retrofit: Retrofit): MyPostApi { + fun provideMyPage3Api(retrofit: Retrofit): MyPage3Api { return retrofit.buildService() } @Provides @Singleton - fun providesMyBlockUserApi(retrofit: Retrofit): MyBlockUserApi { + fun providesMyPostApi(retrofit: Retrofit): MyPostApi { return retrofit.buildService() } @@ -250,6 +286,23 @@ object NetworkModule { return retrofit.buildService() } + @Provides + @Singleton + fun provideStrangerApi(retrofit: Retrofit): OtherApi { + return retrofit.buildService() + } + + @Provides + @Singleton + fun provideFCMApi(retrofit: Retrofit): FCMApi { + return retrofit.buildService() + } + + @Provides + @Singleton + fun provideNaverApi(@Named("naver") retrofit: Retrofit): NaverApi{ + return retrofit.buildService() + } private inline fun Retrofit.buildService(): T { 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 52c71fba..0227f29b 100644 --- a/app/src/main/java/com/umc/ttoklip/di/RepositoryModule.kt +++ b/app/src/main/java/com/umc/ttoklip/di/RepositoryModule.kt @@ -1,14 +1,17 @@ package com.umc.ttoklip.di +import com.umc.ttoklip.data.api.FCMApi import com.umc.ttoklip.data.api.HomeApi import com.umc.ttoklip.data.api.MainCommsApi import com.umc.ttoklip.data.api.MainTogethersApi -import com.umc.ttoklip.data.api.MyAccountRestrictApi -import com.umc.ttoklip.data.api.MyBlockUserApi +//import com.umc.ttoklip.data.api.MyAccountRestrictApi import com.umc.ttoklip.data.api.MyPage2Api +import com.umc.ttoklip.data.api.MyPage3Api import com.umc.ttoklip.data.api.MyPageApi import com.umc.ttoklip.data.api.MyPostApi +import com.umc.ttoklip.data.api.NaverApi import com.umc.ttoklip.data.api.NewsApi +import com.umc.ttoklip.data.api.OtherApi import com.umc.ttoklip.data.api.ReadCommsApi import com.umc.ttoklip.data.api.ReadTogetherApi import com.umc.ttoklip.data.api.Search2Api @@ -16,16 +19,18 @@ import com.umc.ttoklip.data.api.SearchApi import com.umc.ttoklip.data.api.TownMainApi import com.umc.ttoklip.data.api.WriteCommsApi import com.umc.ttoklip.data.api.WriteTogetherApi +import com.umc.ttoklip.data.repository.fcm.FCMRepository +import com.umc.ttoklip.data.repository.fcm.FCMRepositoryImpl import com.umc.ttoklip.data.repository.home.HomeRepository import com.umc.ttoklip.data.repository.home.HomeRepositoryImpl -import com.umc.ttoklip.data.repository.mypage.MyAccountRestrictRepository -import com.umc.ttoklip.data.repository.mypage.MyAccountRestrictRepositoryImpl -import com.umc.ttoklip.data.repository.mypage.MyBlockUserRepository -import com.umc.ttoklip.data.repository.mypage.MyBlockUserRepositoryImpl import com.umc.ttoklip.data.repository.mypage.MyPageRepository2 import com.umc.ttoklip.data.repository.mypage.MyPageRepository2Impl +import com.umc.ttoklip.data.repository.mypage.MyPageRepository3 +import com.umc.ttoklip.data.repository.mypage.MyPageRepository3Impl import com.umc.ttoklip.data.repository.mypage.MyPostRepository import com.umc.ttoklip.data.repository.mypage.MyPostRepositoryImpl +import com.umc.ttoklip.data.repository.naver.NaverRepository +import com.umc.ttoklip.data.repository.naver.NaverRepositoryImpl import com.umc.ttoklip.data.repository.news.NewsRepository import com.umc.ttoklip.data.repository.news.NewsRepositoryImpl import com.umc.ttoklip.data.repository.scrap.ScrapRepository @@ -34,6 +39,8 @@ import com.umc.ttoklip.data.repository.search.Search2Repository import com.umc.ttoklip.data.repository.search.Search2RepositoryImpl import com.umc.ttoklip.data.repository.search.SearchRepository import com.umc.ttoklip.data.repository.search.SearchRepositoryImpl +import com.umc.ttoklip.data.repository.stranger.StrangerRepository +import com.umc.ttoklip.data.repository.stranger.StrangerRepositoryImpl import com.umc.ttoklip.data.repository.town.MainCommsRepository import com.umc.ttoklip.data.repository.town.MainCommsRepositoryImpl import com.umc.ttoklip.data.repository.town.MainTogethersRepository @@ -126,8 +133,8 @@ object RepositoryModule { @Provides @Singleton - fun providesMyAccountRestrictRepository(api: MyAccountRestrictApi): MyAccountRestrictRepository = - MyAccountRestrictRepositoryImpl(api) + fun providesMyPage3Repository(api: MyPage3Api): MyPageRepository3 = + MyPageRepository3Impl(api) @Provides @Singleton @@ -136,12 +143,21 @@ object RepositoryModule { @Provides @Singleton - fun providesMyBlockUserRepository(api: MyBlockUserApi): MyBlockUserRepository = - MyBlockUserRepositoryImpl(api) + fun providesTownMainRepository(api: TownMainApi): TownMainRepository = + TownMainRepositoryImpl(api) @Provides @Singleton - fun providesTownMainRepository(api: TownMainApi): TownMainRepository = - TownMainRepositoryImpl(api) + fun providesStrangerRepository(api: OtherApi): StrangerRepository = + StrangerRepositoryImpl(api) + @Provides + @Singleton + fun providesFCMRepository(api: FCMApi): FCMRepository = + FCMRepositoryImpl(api) + + @Provides + @Singleton + fun providesNaverRepository(api: NaverApi): NaverRepository = + NaverRepositoryImpl(api) } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/MainActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/MainActivity.kt index 9e31aff9..35116041 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/MainActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/MainActivity.kt @@ -7,7 +7,11 @@ import androidx.navigation.ui.setupWithNavController import com.umc.ttoklip.R import com.umc.ttoklip.TtoklipApplication import com.umc.ttoklip.databinding.ActivityMainBinding +import com.umc.ttoklip.util.TtoklipFirebaseMessagingService import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch @AndroidEntryPoint class MainActivity : AppCompatActivity() { @@ -24,6 +28,7 @@ class MainActivity : AppCompatActivity() { val navController = navHostFragment.navController binding.bottomNav.setupWithNavController(navController) + } fun goNews() { diff --git a/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmActivity.kt index 664e3f0b..00580cd2 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmActivity.kt @@ -2,19 +2,43 @@ package com.umc.ttoklip.presentation.alarm import android.content.Context import android.content.Intent -import androidx.activity.viewModels import com.umc.ttoklip.R +import android.util.Log +import androidx.activity.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import com.umc.ttoklip.databinding.ActivityAlarmBinding import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.news.adapter.Dummy +import com.umc.ttoklip.presentation.hometown.together.read.ReadTogetherActivity +import com.umc.ttoklip.presentation.honeytip.read.ReadHoneyTipActivity +import com.umc.ttoklip.presentation.honeytip.read.ReadQuestionActivity import com.umc.ttoklip.presentation.search.adapter.AlarmRVA -import com.umc.ttoklip.presentation.search.adapter.SearchRVA +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch +@AndroidEntryPoint class AlarmActivity : BaseActivity(R.layout.activity_alarm) { - private val viewModel: AlarmViewModel by viewModels() + private val viewModel: AlarmViewModel by viewModels() private val alarmRVA by lazy { - AlarmRVA({}) + AlarmRVA { + when (it.title) { + "꿀팁 공유해요" -> { + startActivity(ReadHoneyTipActivity.newIntent(this, it.targetClassId)) + } + + "우리동네 덧글", "우리동네 답글" -> { + startActivity(ReadTogetherActivity.newIntent(this, it.targetClassId.toLong())) + } + + "질문해요" -> { + startActivity(ReadQuestionActivity.newIntent(this, it.targetClassId)) + } + + else -> Unit + } + } } override fun initView() { @@ -23,22 +47,23 @@ class AlarmActivity : BaseActivity(R.layout.activity_alarm finish() } binding.alarmRV.adapter = alarmRVA - alarmRVA.submitList( - listOf( - Dummy("1"), - Dummy("2") - ) - ) } override fun initObserver() { - + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.notiList.collect { + alarmRVA.submitList(it) + Log.d("확인", "${it.map { it.notificationId }}") + } + } + } } - companion object{ + companion object { const val ALARM = "alarm" - fun newIntent(context : Context) = + fun newIntent(context: Context) = Intent(context, AlarmActivity::class.java) } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmViewModel.kt index a65e0679..b6288ba4 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmViewModel.kt @@ -1,4 +1,115 @@ package com.umc.ttoklip.presentation.alarm -interface AlarmViewModel { +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.TtoklipApplication +import com.umc.ttoklip.data.model.home.NotificationItem +import com.umc.ttoklip.data.model.home.NotificationResponse +import com.umc.ttoklip.data.model.news.News +import com.umc.ttoklip.data.repository.home.HomeRepository +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.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class AlarmViewModel @Inject constructor( + private val repository: HomeRepository +) : ViewModel() { + + private val _notiList = MutableStateFlow>(listOf()) + val notiList: StateFlow> + get() = _notiList + + init { + viewModelScope.launch { + getNotificationsHoney() + getNotificationsQuestion() + getNotificationsTown() + notiList.value.sortedBy { it.notificationId } + } + } + + private fun getNotificationsHoney() { + viewModelScope.launch { + try { + repository.getNotifications("HONEY_TIP_COMMENT") + .onSuccess { + _notiList.emit(notiList.value + it.responses) + repository.getNotifications("HONEY_TIP_CHILD_COMMENT") + .onSuccess { + _notiList.emit(notiList.value + it.responses) + }.onFail { + + }.onException { + throw it + } + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + private fun getNotificationsQuestion() { + viewModelScope.launch { + try { + repository.getNotifications("QUESTION_COMMENT") + .onSuccess { + _notiList.emit(notiList.value + it.responses) + repository.getNotifications("QUESTION_CHILD_COMMENT") + .onSuccess { + _notiList.emit(notiList.value + it.responses) + }.onFail { + + }.onException { + throw it + } + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + private fun getNotificationsTown() { + viewModelScope.launch { + try { + repository.getNotifications("OUR_TOWN_COMMENT") + .onSuccess { + _notiList.emit(notiList.value + it.responses) + repository.getNotifications("OUR_TOWN_CHILD_COMMENT") + .onSuccess { + _notiList.emit(notiList.value + it.responses) + }.onFail { + + }.onException { + throw it + } + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmViewModelImpl.kt deleted file mode 100644 index 43dd896f..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/alarm/AlarmViewModelImpl.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.umc.ttoklip.presentation.alarm - -import androidx.lifecycle.ViewModel - -class AlarmViewModelImpl: AlarmViewModel, ViewModel() { -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/alarm/adapter/AlarmRVA.kt b/app/src/main/java/com/umc/ttoklip/presentation/alarm/adapter/AlarmRVA.kt index 20e4db9d..966d7843 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/alarm/adapter/AlarmRVA.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/alarm/adapter/AlarmRVA.kt @@ -5,17 +5,21 @@ 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.home.NotificationItem import com.umc.ttoklip.databinding.ItemAlarmBinding import com.umc.ttoklip.presentation.news.adapter.Dummy -class AlarmRVA(val onClick: () -> Unit) : ListAdapter(differ) { +class AlarmRVA(val onClick: (NotificationItem) -> Unit) : ListAdapter(differ) { inner class ItemViewHolder( private val binding: ItemAlarmBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: Dummy) { - + fun bind(data: NotificationItem) { + binding.item = data + binding.root.setOnClickListener { + onClick(data) + } } } @@ -37,12 +41,12 @@ class AlarmRVA(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: NotificationItem, newItem: NotificationItem): Boolean { + return oldItem.notificationId == newItem.notificationId } - override fun areContentsTheSame(oldItem: Dummy, newItem: Dummy): Boolean { + override fun areContentsTheSame(oldItem: NotificationItem, newItem: NotificationItem): Boolean { return oldItem == newItem } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/base/BaseDialogFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/base/BaseDialogFragment.kt index 05db9ded..abb65df0 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/base/BaseDialogFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/base/BaseDialogFragment.kt @@ -29,7 +29,7 @@ abstract class BaseDialogFragment(@LayoutRes val layoutReso null, false ) - binding.lifecycleOwner = this + binding.lifecycleOwner = this.viewLifecycleOwner return binding.root } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/DeleteDialogFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/dialog/DeleteDialogFragment.kt similarity index 77% rename from app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/DeleteDialogFragment.kt rename to app/src/main/java/com/umc/ttoklip/presentation/dialog/DeleteDialogFragment.kt index c011fd87..b8003258 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/DeleteDialogFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/dialog/DeleteDialogFragment.kt @@ -1,30 +1,30 @@ -package com.umc.ttoklip.presentation.honeytip.dialog - -import com.umc.ttoklip.R -import com.umc.ttoklip.databinding.DialogDeleteBinding -import com.umc.ttoklip.presentation.base.BaseDialogFragment - -class DeleteDialogFragment: BaseDialogFragment(R.layout.dialog_delete) { - private lateinit var dialogClickListener: DialogClickListener - override fun initObserver() { - - } - - override fun initView() { - binding.cancelBtn.setOnClickListener { - dismiss() - } - binding.acceptBtn.setOnClickListener { - dialogClickListener.onClick() - dismiss() - } - } - - fun setDialogClickListener(dialogClickListener: DialogClickListener){ - this.dialogClickListener = dialogClickListener - } - - interface DialogClickListener{ - fun onClick() - } +package com.umc.ttoklip.presentation.dialog + +import com.umc.ttoklip.R +import com.umc.ttoklip.databinding.DialogDeleteBinding +import com.umc.ttoklip.presentation.base.BaseDialogFragment + +class DeleteDialogFragment: BaseDialogFragment(R.layout.dialog_delete) { + private var dialogClickListener: DialogClickListener? = null + override fun initObserver() { + + } + + override fun initView() { + binding.cancelBtn.setOnClickListener { + dismiss() + } + binding.acceptBtn.setOnClickListener { + dialogClickListener?.onClick() + dismiss() + } + } + + fun setDialogClickListener(dialogClickListener: DialogClickListener){ + this.dialogClickListener = dialogClickListener + } + + interface DialogClickListener{ + fun onClick() + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/dialog/FinishCartDialogFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/dialog/FinishCartDialogFragment.kt new file mode 100644 index 00000000..72154e90 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/dialog/FinishCartDialogFragment.kt @@ -0,0 +1,31 @@ +package com.umc.ttoklip.presentation.dialog + +import com.umc.ttoklip.R +import com.umc.ttoklip.databinding.DialogCartFinishBinding +import com.umc.ttoklip.databinding.DialogDeleteBinding +import com.umc.ttoklip.presentation.base.BaseDialogFragment + +class FinishCartDialogFragment: BaseDialogFragment(R.layout.dialog_cart_finish) { + private var dialogClickListener: DialogClickListener? = null + override fun initObserver() { + + } + + override fun initView() { + binding.cancelBtn.setOnClickListener { + dismiss() + } + binding.acceptBtn.setOnClickListener { + dialogClickListener?.onClick() + dismiss() + } + } + + fun setDialogClickListener(dialogClickListener: DialogClickListener){ + this.dialogClickListener = dialogClickListener + } + + interface DialogClickListener{ + fun onClick() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ImageDialog.kt b/app/src/main/java/com/umc/ttoklip/presentation/dialog/ImageDialog.kt similarity index 95% rename from app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ImageDialog.kt rename to app/src/main/java/com/umc/ttoklip/presentation/dialog/ImageDialog.kt index 51957799..0961ea83 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ImageDialog.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/dialog/ImageDialog.kt @@ -1,4 +1,4 @@ -package com.umc.ttoklip.presentation.honeytip.dialog +package com.umc.ttoklip.presentation.dialog import android.app.Dialog import android.content.Context diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ImageDialogFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/dialog/ImageDialogFragment.kt similarity index 93% rename from app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ImageDialogFragment.kt rename to app/src/main/java/com/umc/ttoklip/presentation/dialog/ImageDialogFragment.kt index 3b81ddf0..65f6905e 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ImageDialogFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/dialog/ImageDialogFragment.kt @@ -1,4 +1,4 @@ -package com.umc.ttoklip.presentation.honeytip.dialog +package com.umc.ttoklip.presentation.dialog import com.umc.ttoklip.R import com.umc.ttoklip.databinding.DialogImageBinding diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ReportDialogFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/dialog/ReportDialogFragment.kt similarity index 94% rename from app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ReportDialogFragment.kt rename to app/src/main/java/com/umc/ttoklip/presentation/dialog/ReportDialogFragment.kt index 71c3d657..18af936a 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/dialog/ReportDialogFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/dialog/ReportDialogFragment.kt @@ -1,96 +1,97 @@ -package com.umc.ttoklip.presentation.honeytip.dialog - -import CustomSpinnerAdapter -import android.app.Dialog -import android.content.Context -import android.graphics.Point -import android.os.Build -import android.util.Log -import android.view.WindowManager -import com.umc.ttoklip.R -import com.umc.ttoklip.data.model.honeytip.request.ReportRequest -import com.umc.ttoklip.databinding.DialogReportBinding -import com.umc.ttoklip.presentation.base.BaseDialogFragment - -class ReportDialogFragment: BaseDialogFragment(R.layout.dialog_report), CustomSpinnerAdapter.GetSpinnerTextListener { - private lateinit var dialogClickListener: DialogClickListener - private var reportType = "" - override fun initObserver() { - - } - - override fun initView() { - val list = arrayListOf( - "신고사유", - "낚시 / 중복 / 도배성 게시물", - "상업적 광고 / 홍보 글", - "선정적 / 불쾌함이 느껴지는 부적절한 글", - "비방 / 욕설 / 혐오 표현이 사용된 글", - "종교 / 포교 관련 글", - "게시판 성격에 부적절", - "유출 / 사칭 / 사기", - ) - val adapter = CustomSpinnerAdapter(requireContext(), list, this) - binding.spinner.adapter = adapter - binding.cancelBtn.setOnClickListener { - dismiss() - } - binding.acceptBtn.setOnClickListener { - dialogClickListener.onClick(content = binding.reasonEt.text.toString(), type = stringToEnum(reportType)) - dismiss() - } - } - - fun setDialogClickListener(dialogClickListener: DialogClickListener){ - this.dialogClickListener = dialogClickListener - } - - interface DialogClickListener{ - fun onClick(type: String, content : String) - } - - private fun resize(dialog: Dialog, width: Float, height: Float){ - val windowManager = context?.getSystemService(Context.WINDOW_SERVICE) as WindowManager - - if (Build.VERSION.SDK_INT < 30) { - val size = Point() - windowManager.defaultDisplay.getSize(size) - - val x = (size.x * width).toInt() - val y = (size.y * height).toInt() - dialog.window?.setLayout(x, y) - } else { - val rect = windowManager.currentWindowMetrics.bounds - - val x = (rect.width() * width).toInt() - val y = (rect.height() * height).toInt() - dialog.window?.setLayout(x, y) - } - } - - override fun getText(text: String) { - reportType = text - Log.d("reportType", reportType.toString()) - } - - private fun stringToEnum(reportType: String): String { - return when (reportType) { - "낚시 / 중복 / 도배성 게시물" -> ReportType.FISHING_DUPLICATE_SPAM.toString() - "상업적 광고 / 홍보 글" -> ReportType.COMMERCIAL_ADVERTISING.toString() - "선정적 / 불쾌함이 느껴지는 부적절한 글" -> ReportType.INAPPROPRIATE_CONTENT.toString() - "비방 / 욕설 / 혐오 표현이 사용된 글" -> ReportType.ABUSE.toString() - "종교 / 포교 관련 글" -> ReportType.RELIGIOUS_PROSELYTIZING.toString() - "게시판 성격에 부적절" -> ReportType.INAPPROPRIATE_FOR_FORUM.toString() - else -> ReportType.LEAK_IMPERSONATION_FRAUD.toString() - } - } - enum class ReportType{ - FISHING_DUPLICATE_SPAM, - COMMERCIAL_ADVERTISING, - INAPPROPRIATE_CONTENT, - ABUSE, - RELIGIOUS_PROSELYTIZING, - INAPPROPRIATE_FOR_FORUM, - LEAK_IMPERSONATION_FRAUD - } +package com.umc.ttoklip.presentation.dialog + +import CustomSpinnerAdapter +import android.app.Dialog +import android.content.Context +import android.graphics.Point +import android.os.Build +import android.util.Log +import android.view.WindowManager +import com.umc.ttoklip.R +import com.umc.ttoklip.data.model.honeytip.request.ReportRequest +import com.umc.ttoklip.databinding.DialogReportBinding +import com.umc.ttoklip.presentation.base.BaseDialogFragment + +class ReportDialogFragment: BaseDialogFragment(R.layout.dialog_report), CustomSpinnerAdapter.GetSpinnerTextListener { + private lateinit var dialogClickListener: DialogClickListener + private var reportType = "" + override fun initObserver() { + + } + + override fun initView() { + val list = arrayListOf( + "신고사유", + "낚시 / 중복 / 도배성 게시물", + "상업적 광고 / 홍보 글", + "선정적 / 불쾌함이 느껴지는 부적절한 글", + "비방 / 욕설 / 혐오 표현이 사용된 글", + "종교 / 포교 관련 글", + "게시판 성격에 부적절", + "유출 / 사칭 / 사기", + ) + val adapter = CustomSpinnerAdapter(requireContext(), list, this) + binding.spinner.adapter = adapter + binding.cancelBtn.setOnClickListener { + dismiss() + } + binding.acceptBtn.setOnClickListener { + dialogClickListener.onClick(content = binding.reasonEt.text.toString(), type = stringToEnum(reportType)) + dismiss() + } + } + + fun setDialogClickListener(dialogClickListener: DialogClickListener){ + this.dialogClickListener = dialogClickListener + } + + interface DialogClickListener{ + fun onClick(type: String, content : String) + } + + private fun resize(dialog: Dialog, width: Float, height: Float){ + val windowManager = context?.getSystemService(Context.WINDOW_SERVICE) as WindowManager + + if (Build.VERSION.SDK_INT < 30) { + val size = Point() + windowManager.defaultDisplay.getSize(size) + + val x = (size.x * width).toInt() + val y = (size.y * height).toInt() + dialog.window?.setLayout(x, y) + } else { + val rect = windowManager.currentWindowMetrics.bounds + + val x = (rect.width() * width).toInt() + val y = (rect.height() * height).toInt() + dialog.window?.setLayout(x, y) + } + } + + override fun getText(text: String) { + reportType = text + Log.d("reportType", reportType.toString()) + } + + private fun stringToEnum(reportType: String): String { + return when (reportType) { + "낚시 / 중복 / 도배성 게시물" -> ReportType.FISHING_DUPLICATE_SPAM.toString() + "상업적 광고 / 홍보 글" -> ReportType.COMMERCIAL_ADVERTISING.toString() + "선정적 / 불쾌함이 느껴지는 부적절한 글" -> ReportType.INAPPROPRIATE_CONTENT.toString() + "비방 / 욕설 / 혐오 표현이 사용된 글" -> ReportType.ABUSE.toString() + "종교 / 포교 관련 글" -> ReportType.RELIGIOUS_PROSELYTIZING.toString() + "게시판 성격에 부적절" -> ReportType.INAPPROPRIATE_FOR_FORUM.toString() + "유출 / 사칭 / 사기" -> ReportType.LEAK_IMPERSONATION_FRAUD.toString() + else -> "" + } + } + enum class ReportType{ + FISHING_DUPLICATE_SPAM, + COMMERCIAL_ADVERTISING, + INAPPROPRIATE_CONTENT, + ABUSE, + RELIGIOUS_PROSELYTIZING, + INAPPROPRIATE_FOR_FORUM, + LEAK_IMPERSONATION_FRAUD + } } \ 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 7a85fd20..f436b8b2 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 @@ -16,9 +16,9 @@ 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.ReadTogetherActivity -import com.umc.ttoklip.presentation.hometown.TogetherActivity +import com.umc.ttoklip.presentation.hometown.communication.CommunicationActivity +import com.umc.ttoklip.presentation.hometown.together.read.ReadTogetherActivity +import com.umc.ttoklip.presentation.hometown.together.TogetherActivity import com.umc.ttoklip.presentation.honeytip.adapter.OnItemClickListener import com.umc.ttoklip.presentation.honeytip.read.ReadHoneyTipActivity import com.umc.ttoklip.presentation.mypage.adapter.OnTogetherItemClickListener @@ -26,7 +26,10 @@ 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.search2.SearchActivity2 +import com.umc.ttoklip.util.TtoklipFirebaseMessagingService import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @AndroidEntryPoint @@ -93,8 +96,12 @@ class HomeFragment : BaseFragment(R.layout.fragment_home), binding.vm = viewModel binding.tipRV.adapter = tipRVA viewModel.getMain() - TtoklipApplication.prefs.setString("nickname","이강인") - Log.d("엑세스","${TtoklipApplication.prefs.getString("jwt","")}") + viewModel.fetchGeocoding("분당구 불정로 6") + Log.d("엑세스", "${TtoklipApplication.prefs.getString("jwt", "")}") + + CoroutineScope(Dispatchers.IO).launch { + viewModel.patchFCM(TtoklipFirebaseMessagingService().getFirebaseToken()) + } binding.chatImg.setOnClickListener { val intent = Intent(requireContext(), CommunicationActivity::class.java) @@ -104,9 +111,6 @@ class HomeFragment : BaseFragment(R.layout.fragment_home), val intent = Intent(requireContext(), TogetherActivity::class.java) startActivity(intent) } - //테스트 - binding.weatherImg.setImageResource(Weather.CLOUD.resId) - binding.weatherTitle.text = Weather.CLOUD.label binding.newsRV.adapter = newsRVA binding.groupBuyRV.adapter = townRVA diff --git a/app/src/main/java/com/umc/ttoklip/presentation/home/HomeViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/home/HomeViewModel.kt index e40d502c..a8d9528e 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/home/HomeViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/home/HomeViewModel.kt @@ -5,10 +5,10 @@ import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow interface HomeViewModel { - val haveWork : StateFlow - val doneWork : StateFlow - val activityBus : SharedFlow - val mainData : StateFlow + val haveWork: StateFlow + val doneWork: StateFlow + val activityBus: SharedFlow + val mainData: StateFlow fun clickDelayWork() fun clickDoneWork() @@ -18,8 +18,11 @@ interface HomeViewModel { fun clickAlarm() fun clickSearch() fun getMain() + fun patchFCM(token: String) - enum class ActivityEventBus{ + fun fetchGeocoding(query: String) + + enum class ActivityEventBus { SEARCH, NEWS_DETAIL, TIP_DETAIL, diff --git a/app/src/main/java/com/umc/ttoklip/presentation/home/HomeViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/home/HomeViewModelImpl.kt index d822ea6e..a55b84d6 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/home/HomeViewModelImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/home/HomeViewModelImpl.kt @@ -5,8 +5,12 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.TtoklipApplication +import com.umc.ttoklip.data.model.fcm.FCMTokenRequest import com.umc.ttoklip.data.model.home.HomeResponse +import com.umc.ttoklip.data.repository.fcm.FCMRepository import com.umc.ttoklip.data.repository.home.HomeRepository +import com.umc.ttoklip.data.repository.naver.NaverRepository import com.umc.ttoklip.module.NetworkResult import com.umc.ttoklip.module.onException import com.umc.ttoklip.module.onFail @@ -23,7 +27,9 @@ import javax.inject.Inject @HiltViewModel class HomeViewModelImpl @Inject constructor( - private val homeRepository: HomeRepository + private val homeRepository: HomeRepository, + private val fcmRepository: FCMRepository, + private val naverRepository: NaverRepository ) : ViewModel(), HomeViewModel { private val _haveWork: MutableStateFlow = MutableStateFlow(true) @@ -90,15 +96,42 @@ class HomeViewModelImpl @Inject constructor( homeRepository.getHomeMain() .onSuccess { _mainData.emit(it) + TtoklipApplication.prefs.setString("nickname", it.currentMemberNickname) }.onFail { - }.onException { - throw it - } + }.onException { + throw it + } } catch (e: Exception) { e.printStackTrace() Log.d("예외", "$e") } } } + + override fun patchFCM(token: String) { + viewModelScope.launch { + try { + fcmRepository.patchFCMToken(FCMTokenRequest(token)) + .onSuccess { + + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + override fun fetchGeocoding(query: String) { + viewModelScope.launch { + naverRepository.fetchGeocoding(query).onSuccess { + Log.d("naver", it.toString()) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/MyHometownFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/MyHometownFragment.kt index 579e6017..8bf6f963 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/MyHometownFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/MyHometownFragment.kt @@ -15,8 +15,13 @@ import com.umc.ttoklip.databinding.FragmentMyHometownBinding import com.umc.ttoklip.presentation.alarm.AlarmActivity import com.umc.ttoklip.presentation.base.BaseFragment import com.umc.ttoklip.presentation.hometown.adapter.OnTogetherClickListener -import com.umc.ttoklip.presentation.hometown.adapter.Together import com.umc.ttoklip.presentation.hometown.adapter.TogetherAdapter +import com.umc.ttoklip.presentation.hometown.communication.CommunicationActivity +import com.umc.ttoklip.presentation.hometown.communication.read.ReadCommunicationActivity +import com.umc.ttoklip.presentation.hometown.communication.write.WriteCommunicationActivity +import com.umc.ttoklip.presentation.hometown.together.read.ReadTogetherActivity +import com.umc.ttoklip.presentation.hometown.together.TogetherActivity +import com.umc.ttoklip.presentation.hometown.together.write.WriteTogetherActivity import com.umc.ttoklip.presentation.mypage.MyHometownAddressActivity import com.umc.ttoklip.presentation.search.SearchActivity import dagger.hilt.android.AndroidEntryPoint @@ -68,7 +73,6 @@ class MyHometownFragment : BaseFragment(R.layout.frag val intent = Intent(requireContext(), TogetherActivity::class.java) startActivity(intent) } - viewModel.getM() binding.seeDetailCommunicationBtn.setOnClickListener { val intent = Intent(requireContext(), CommunicationActivity::class.java) @@ -135,4 +139,9 @@ class MyHometownFragment : BaseFragment(R.layout.frag startActivity(intent) } } + + override fun onResume() { + super.onResume() + viewModel.getM() + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationViewModel.kt deleted file mode 100644 index c1c577db..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationViewModel.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.umc.ttoklip.presentation.hometown - -import com.umc.ttoklip.data.model.town.CreateCommentRequest -import com.umc.ttoklip.data.model.town.ReportRequest -import com.umc.ttoklip.data.model.town.ViewCommunicationResponse -import kotlinx.coroutines.flow.StateFlow - -interface ReadCommunicationViewModel { - val postId: StateFlow - val postContent: StateFlow - val like: StateFlow - val scrap: StateFlow - - fun savePostId(postId: Long) - fun readCommunication(postId: Long) - fun changeScrap() - fun changeLike() - fun reportPost(reportRequest: ReportRequest) - fun reportComment(commentId: Long, reportRequest: ReportRequest) - fun deleteComment(commentId: Long) - fun createComment(body: CreateCommentRequest) - -} \ No newline at end of file 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 deleted file mode 100644 index 9cefa8f2..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherActivity.kt +++ /dev/null @@ -1,216 +0,0 @@ -package com.umc.ttoklip.presentation.hometown - -import android.content.Context -import android.content.Intent -import android.graphics.Rect -import android.text.SpannableString -import android.text.style.ForegroundColorSpan -import android.util.Log -import android.view.MotionEvent -import android.view.inputmethod.InputMethodManager -import android.widget.EditText -import androidx.activity.viewModels -import androidx.core.view.isVisible -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle -import com.umc.ttoklip.R -import com.umc.ttoklip.data.model.honeytip.ImageUrl -import com.umc.ttoklip.data.model.town.CreateCommentRequest -import com.umc.ttoklip.databinding.ActivityReadTogetherBinding -import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.hometown.adapter.TownCommentAdapter -import com.umc.ttoklip.presentation.honeytip.ImageViewActivity -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 dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch - -@AndroidEntryPoint -class ReadTogetherActivity : - BaseActivity(R.layout.activity_read_together), - OnReadImageClickListener { - private val viewModel: ReadTogetherViewModel by viewModels() - private val imageAdapter: ReadImageRVA by lazy { - ReadImageRVA(this, this@ReadTogetherActivity) - } - private val commentRVA by lazy { - TownCommentAdapter({}, { commentId, reportRequest -> - if (reportRequest != null) { - viewModel.reportComment(commentId, reportRequest) - } else { - viewModel.deleteComment(commentId) - } - }) - } - private var postId = 0L - - override fun initView() { - binding.imageRv.adapter = imageAdapter - binding.commentRv.adapter = commentRVA - binding.vm = viewModel - postId = intent.getLongExtra("postId", 0) - viewModel.savePostId(postId) - binding.reportBtn.bringToFront() - - - binding.deleteBtn.setOnClickListener { - val deleteDialog = DeleteDialogFragment() - deleteDialog.setDialogClickListener(object : DeleteDialogFragment.DialogClickListener { - override fun onClick() { - - } - }) - deleteDialog.show(supportFragmentManager, deleteDialog.tag) - } - binding.backBtn.setOnClickListener { - finish() - } - - binding.dotBtn.setOnClickListener { - binding.reportBtn.isVisible = binding.reportBtn.isVisible.not() - } - - binding.reportBtn.setOnClickListener { - val reportDialog = ReportDialogFragment() - reportDialog.setDialogClickListener(object : ReportDialogFragment.DialogClickListener { - override fun onClick(type: String, content: String) { - - } - - }) - reportDialog.show(supportFragmentManager, reportDialog.tag) - } - - - binding.cardView.setOnClickListener { - CoroutineScope(Dispatchers.IO).launch { - if (binding.commentEt.text.toString().isNotBlank()) { - viewModel.createComment( - CreateCommentRequest( - binding.commentEt.text.toString(), - 0L - ) - ) - delay(500) - viewModel.readTogether(postId) - } - } - } - - } - - override fun initObserver() { - with(lifecycleScope) { - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.joinState.collect { - if (it.not()) { - binding.joinBtn.background = - getDrawable(R.drawable.rectangle_corner_10_strok_1_gray40) -// binding.joinBtn.text = getString(R.string.cancel_join) - } else { - binding.joinBtn.background = - getDrawable(R.drawable.yellow_btn_background) -// binding.joinBtn.text = getString(R.string.join_together) - } - } - } - } - - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.postId.collect { - viewModel.readTogether(it) - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.postContent.collect { response -> - with(binding) { - writerTv.text = response.writer - titleT.text = response.title - contentT.text = response.content - totalPriceTv.text = response.totalPrice.toString() - maxMemberTv.text = response.partyMax.toString() - tradingPlaceTv.text = response.location - openChatLinkTv.text = response.chatUrl - - - - imageAdapter.submitList(response.imageUrls.map { url -> - ImageUrl( - imageUrl = url.imageUrl - ) - }) - commentRVA.submitList(response.commentResponses) - val spannableAmount = - SpannableString( - getString( - R.string.join_stat_format, - response.partyCnt, - response.partyMax - ) - ) - spannableAmount.setSpan( - ForegroundColorSpan(getColor(R.color.blue)), - AMOUNT_STRING_START, - response.partyCnt.toString().length + AMOUNT_STRING_LENGTH, - SPANNABLE_FLAG_ZERO - ) - binding.currentJoinStatTv.text = spannableAmount - } - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - - } - } - } - } - - override fun dispatchTouchEvent(event: MotionEvent?): Boolean { - if (event?.action == MotionEvent.ACTION_DOWN) { - val v = currentFocus - if (v is EditText) { - val outRect = Rect() - v.getGlobalVisibleRect(outRect) - if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) { - v.clearFocus() - val imm: InputMethodManager = - getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(v.getWindowToken(), 0) - } - } - } - return super.dispatchTouchEvent(event) - } - - companion object { - private const val AMOUNT_STRING_START = 0 - private const val SPANNABLE_FLAG_ZERO = 0 - private const val AMOUNT_STRING_LENGTH = 1 - } - - override fun onClick(imageUrl: String) { - val images = imageAdapter.currentList.filterIsInstance().map { it.imageUrl } - .toTypedArray() - Log.d("images", images.toString()) - val intent = Intent(this, ImageViewActivity::class.java) - intent.putExtra("images", images) - startActivity(intent) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/TradeLocationActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/TradeLocationActivity.kt index 25ca17cd..9103616c 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/TradeLocationActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/TradeLocationActivity.kt @@ -10,6 +10,7 @@ import com.umc.ttoklip.presentation.base.BaseActivity import com.umc.ttoklip.presentation.hometown.adapter.OnRecentPlaceClickListener import com.umc.ttoklip.presentation.hometown.adapter.RecentPlace import com.umc.ttoklip.presentation.hometown.adapter.RecentlyUsedPlaceAdapter +import com.umc.ttoklip.presentation.hometown.together.write.WriteTogetherActivity import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/adapter/TownCommentAdapter.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/adapter/TownCommentAdapter.kt index 19891137..cdd64c3e 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/adapter/TownCommentAdapter.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/adapter/TownCommentAdapter.kt @@ -9,7 +9,7 @@ import com.umc.ttoklip.data.model.town.CommentResponse import com.umc.ttoklip.data.model.town.ReportRequest import com.umc.ttoklip.databinding.ItemTownCommentBinding import com.umc.ttoklip.databinding.ItemTownCommentReplyBinding -import com.umc.ttoklip.presentation.honeytip.dialog.ReportDialogFragment +import com.umc.ttoklip.presentation.dialog.ReportDialogFragment class TownCommentAdapter( val replyComment: (Long) -> Unit, diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/CommunicationActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/CommunicationActivity.kt similarity index 75% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/CommunicationActivity.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/CommunicationActivity.kt index 9963796f..44462e9c 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/CommunicationActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/CommunicationActivity.kt @@ -1,10 +1,11 @@ -package com.umc.ttoklip.presentation.hometown +package com.umc.ttoklip.presentation.hometown.communication import android.content.Intent import androidx.activity.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle +import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import com.umc.ttoklip.R import com.umc.ttoklip.data.model.town.Communities @@ -13,6 +14,8 @@ import com.umc.ttoklip.presentation.alarm.AlarmActivity import com.umc.ttoklip.presentation.base.BaseActivity import com.umc.ttoklip.presentation.hometown.adapter.CommunicationAdapter import com.umc.ttoklip.presentation.hometown.adapter.OnItemClickListener +import com.umc.ttoklip.presentation.hometown.communication.read.ReadCommunicationActivity +import com.umc.ttoklip.presentation.hometown.communication.write.WriteCommunicationActivity import com.umc.ttoklip.presentation.mypage.SortSpinnerAdapter import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -21,7 +24,7 @@ import kotlinx.coroutines.launch class CommunicationActivity : BaseActivity(R.layout.activity_communication), OnItemClickListener { - private val adapter by lazy { + private val rva by lazy { CommunicationAdapter(this) } private val viewModel: CommunicationViewModel by viewModels() @@ -46,12 +49,25 @@ class CommunicationActivity : - binding.communicationRv.layoutManager = LinearLayoutManager(this) - binding.communicationRv.adapter = adapter + binding.communicationRv.apply { + adapter = adapter + layoutManager = LinearLayoutManager(this@CommunicationActivity) + adapter = rva + addItemDecoration( + DividerItemDecoration( + this@CommunicationActivity, + LinearLayoutManager.VERTICAL + ) + ) + } binding.backBtn.setOnClickListener { finish() } + } + + override fun onResume() { + super.onResume() viewModel.getCommunities() } @@ -61,7 +77,7 @@ class CommunicationActivity : launch { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.communities.collect { - adapter.submitList(it) + rva.submitList(it) } } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/CommunicationViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/CommunicationViewModel.kt similarity index 77% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/CommunicationViewModel.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/CommunicationViewModel.kt index 25e7be7e..91349588 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/CommunicationViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/CommunicationViewModel.kt @@ -1,4 +1,4 @@ -package com.umc.ttoklip.presentation.hometown +package com.umc.ttoklip.presentation.hometown.communication import com.umc.ttoklip.data.model.town.Communities import kotlinx.coroutines.flow.StateFlow diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/CommunicationViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/CommunicationViewModelImpl.kt similarity index 84% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/CommunicationViewModelImpl.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/CommunicationViewModelImpl.kt index d7c8de2f..305ac453 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/CommunicationViewModelImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/CommunicationViewModelImpl.kt @@ -1,39 +1,37 @@ -package com.umc.ttoklip.presentation.hometown - -import android.util.Log -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.umc.ttoklip.data.model.town.Communities -import com.umc.ttoklip.data.repository.town.MainCommsRepository -import com.umc.ttoklip.module.onError -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 CommunicationViewModelImpl @Inject constructor(private val repository: MainCommsRepository) : - ViewModel(), CommunicationViewModel { - private val _communities = MutableStateFlow>(emptyList()) - override val communities: StateFlow> - get() = _communities - - val isEnd = MutableStateFlow(false) - - val age = MutableStateFlow(1) - - override fun getCommunities() { - viewModelScope.launch { - repository.getComms().onSuccess { - _communities.value = it.communities - }.onError { - - } - } - } +package com.umc.ttoklip.presentation.hometown.communication + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.town.Communities +import com.umc.ttoklip.data.repository.town.MainCommsRepository +import com.umc.ttoklip.module.onError +import com.umc.ttoklip.module.onSuccess +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class CommunicationViewModelImpl @Inject constructor(private val repository: MainCommsRepository) : + ViewModel(), CommunicationViewModel { + private val _communities = MutableStateFlow>(emptyList()) + override val communities: StateFlow> + get() = _communities + + val isEnd = MutableStateFlow(false) + + val age = MutableStateFlow(1) + + override fun getCommunities() { + viewModelScope.launch { + repository.getComms().onSuccess { + _communities.value = it.communities + Log.d("getComms", it.toString()) + }.onError { + + } + } + } } \ 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/communication/read/ReadCommunicationActivity.kt similarity index 59% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationActivity.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/read/ReadCommunicationActivity.kt index 416a2353..c78c7634 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/read/ReadCommunicationActivity.kt @@ -1,237 +1,276 @@ -package com.umc.ttoklip.presentation.hometown - -import android.content.Context -import android.content.Intent -import android.graphics.Rect -import android.util.Log -import android.view.MotionEvent -import android.view.inputmethod.InputMethodManager -import android.widget.EditText -import androidx.activity.viewModels -import androidx.core.view.isVisible -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle -import com.umc.ttoklip.R -import com.umc.ttoklip.data.model.honeytip.ImageUrl -import com.umc.ttoklip.data.model.town.CreateCommentRequest -import com.umc.ttoklip.data.model.town.ReportRequest -import com.umc.ttoklip.databinding.ActivityReadCommunicationBinding -import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.hometown.adapter.TownCommentAdapter -import com.umc.ttoklip.presentation.honeytip.ImageViewActivity -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 dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch - -@AndroidEntryPoint -class ReadCommunicationActivity : - BaseActivity(R.layout.activity_read_communication), - OnReadImageClickListener { - private val commentRVA by lazy { - TownCommentAdapter({}, { commentId, reportRequest -> - if (reportRequest != null) { - viewModel.reportComment(commentId, reportRequest) - } else { - viewModel.deleteComment(commentId) - } - }) - } - private val imageAdapter: ReadImageRVA by lazy { - ReadImageRVA(this, this@ReadCommunicationActivity) - } - private val viewModel: ReadCommunicationViewModel by viewModels() - private var postId = 0L - - override fun initView() { - binding.imageRv.adapter = imageAdapter - binding.commentRv.adapter = commentRVA - binding.reportBtn.bringToFront() - postId = intent.getLongExtra("postId", 0) - viewModel.savePostId(postId) - - binding.backBtn.setOnClickListener { - finish() - } - - binding.dotBtn.setOnClickListener { - binding.reportBtn.isVisible = true - } - - binding.reportBtn.setOnClickListener { - val reportDialog = ReportDialogFragment() - reportDialog.setDialogClickListener(object : ReportDialogFragment.DialogClickListener { - override fun onClick(type: String, content: String) { - viewModel.reportPost(ReportRequest(content = content, reportType = type)) - } - - }) - reportDialog.show(supportFragmentManager, reportDialog.tag) - } - - binding.deleteBtn.setOnClickListener { - val deleteDialog = DeleteDialogFragment() - deleteDialog.setDialogClickListener(object : DeleteDialogFragment.DialogClickListener { - override fun onClick() { - - } - }) - deleteDialog.show(supportFragmentManager, deleteDialog.tag) - } - - binding.cardView.setOnClickListener { - if (binding.commentEt.text.toString().isNotBlank()) { - CoroutineScope(Dispatchers.IO).launch { - viewModel.createComment( - CreateCommentRequest( - binding.commentEt.text.toString(), - 0L - ) - ) - delay(500) - viewModel.readCommunication(postId) - } - } - } - - binding.scrapBtn.setOnClickListener { - CoroutineScope(Dispatchers.IO).launch { - viewModel.changeScrap() - delay(500) - viewModel.readCommunication(postId) - } - } - binding.likeBtn.setOnClickListener { - CoroutineScope(Dispatchers.IO).launch { - viewModel.changeLike() - delay(500) - viewModel.readCommunication(postId) - } - } - - binding.editBtn.setOnClickListener { - - } - } - - override fun initObserver() { - with(lifecycleScope) { - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.postId.collect { - if (it != 0L) { - viewModel.readCommunication(it) - } - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.postContent.collect { response -> - with(binding) { - writerTv.text = response.writer - titleTv.text = response.title - contentT.text = response.content - - - Log.d("image", response.imageUrls.toString()) - imageAdapter.submitList(response.imageUrls.map { url -> - ImageUrl(url.imageUrl) - }) - if (response.writer == " 1") { - communityMenu.bringToFront() - } - likeT.text = response.likeCount.toString() - bookmarkT.text = response.scrapCount.toString() - commitT.text = response.commentCount.toString() - if (response.likedByCurrentUser) { - likeImg.setImageDrawable(getDrawable(R.drawable.ic_heart_on_20)) - } else { - likeImg.setImageDrawable(getDrawable(R.drawable.ic_heart_off_20)) - } - if (response.scrapedByCurrentUser) { - bookmarkImg.setImageDrawable(getDrawable(R.drawable.ic_bookmark_on_20)) - } else { - bookmarkImg.setImageDrawable(getDrawable(R.drawable.ic_bookmark_off_20)) - } -// Log.d("comment", response.commentResponse.toString()) - commentRVA.submitList(response.commentResponses) - } - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.like.collect { - if (it) { - binding.likeImg.setImageDrawable(getDrawable(R.drawable.ic_heart_on_20)) - } else { - binding.likeImg.setImageDrawable(getDrawable(R.drawable.ic_heart_off_20)) - } - } - } - } - - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.scrap.collect { - if (it) { - binding.bookmarkImg.setImageDrawable(getDrawable(R.drawable.ic_bookmark_on_20)) - } else { - binding.bookmarkImg.setImageDrawable(getDrawable(R.drawable.ic_bookmark_off_20)) - } - } - } - } - - - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.scrap.collect { - - } - } - } - } - } - - override fun dispatchTouchEvent(event: MotionEvent?): Boolean { - if (event?.action == MotionEvent.ACTION_DOWN) { - val v = currentFocus - if (v is EditText) { - val outRect = Rect() - v.getGlobalVisibleRect(outRect) - if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) { - v.clearFocus() - val imm: InputMethodManager = - getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(v.getWindowToken(), 0) - } - } - } - return super.dispatchTouchEvent(event) - } - - override fun onClick(imageUrl: String) { - val images = imageAdapter.currentList.filterIsInstance().map { it.imageUrl } - .toTypedArray() - Log.d("images", images.toString()) - val intent = Intent(this, ImageViewActivity::class.java) - intent.putExtra("images", images) - startActivity(intent) - } - - companion object { - const val COMMUNICATION = "postId" - fun newIntent(context: Context, id: Long) = - Intent(context, ReadCommunicationActivity::class.java).apply { - putExtra(COMMUNICATION, id) - } - } +package com.umc.ttoklip.presentation.hometown.communication.read + +import android.content.Context +import android.content.Intent +import android.graphics.Rect +import android.util.Log +import android.view.MotionEvent +import android.view.View +import android.view.inputmethod.InputMethodManager +import android.widget.EditText +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.TtoklipApplication +import com.umc.ttoklip.data.model.honeytip.ImageUrl +import com.umc.ttoklip.data.model.news.comment.NewsCommentResponse +import com.umc.ttoklip.data.model.town.ReportRequest +import com.umc.ttoklip.databinding.ActivityReadCommunicationBinding +import com.umc.ttoklip.presentation.base.BaseActivity +import com.umc.ttoklip.presentation.honeytip.ImageViewActivity +import com.umc.ttoklip.presentation.honeytip.adapter.OnReadImageClickListener +import com.umc.ttoklip.presentation.honeytip.adapter.ReadImageRVA +import com.umc.ttoklip.presentation.dialog.DeleteDialogFragment +import com.umc.ttoklip.presentation.dialog.ReportDialogFragment +import com.umc.ttoklip.presentation.news.adapter.CommentRVA +import com.umc.ttoklip.presentation.otheruser.OtherUserActivity +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class ReadCommunicationActivity : + BaseActivity(R.layout.activity_read_communication), + OnReadImageClickListener { + private val commentRVA by lazy { + CommentRVA({ id -> + viewModel.replyCommentParentId.value = id + }, { id, myComment -> + if (myComment) { + val deleteDialog = DeleteDialogFragment() + deleteDialog.setDialogClickListener(object : + DeleteDialogFragment.DialogClickListener { + override fun onClick() { + viewModel.deleteComment(id.toLong()) + } + }) + deleteDialog.show(supportFragmentManager, deleteDialog.tag) + } else { + + val reportDialog = ReportDialogFragment() + reportDialog.setDialogClickListener(object : + ReportDialogFragment.DialogClickListener { + override fun onClick(type: String, content: String) { + viewModel.reportComment( + id.toLong(), + com.umc.ttoklip.data.model.honeytip.request.ReportRequest( + content = content, + reportType = type + ) + ) + } + }) + reportDialog.show(supportFragmentManager, reportDialog.tag) + } + }, { nick -> + startActivity(OtherUserActivity.newIntent(this, nick)) + }) + } + private val imageAdapter: ReadImageRVA by lazy { + ReadImageRVA(this, this@ReadCommunicationActivity) + } + private val viewModel: ReadCommunicationViewModel by viewModels() + private var postId = 0L + private var isShowMenu = false + + override fun initView() { + binding.vm = viewModel + binding.imageRv.apply { + adapter = imageAdapter + itemAnimator = null + } + binding.replyT.setOnClickListener { + viewModel.replyCommentParentId.value = 0 + } + binding.commentRv.adapter = commentRVA + binding.reportBtn.bringToFront() + postId = intent.getLongExtra("postId", 0) + viewModel.savePostId(postId) + + binding.backBtn.setOnClickListener { + finish() + } + + binding.reportBtn.setOnClickListener { + val reportDialog = ReportDialogFragment() + reportDialog.setDialogClickListener(object : ReportDialogFragment.DialogClickListener { + override fun onClick(type: String, content: String) { + viewModel.reportPost(ReportRequest(content = content, reportType = type)) + } + + }) + reportDialog.show(supportFragmentManager, reportDialog.tag) + } + + binding.deleteBtn.setOnClickListener { + val deleteDialog = DeleteDialogFragment() + deleteDialog.setDialogClickListener(object : DeleteDialogFragment.DialogClickListener { + override fun onClick() { + viewModel.deleteCommunication() + finish() + } + }) + deleteDialog.show(supportFragmentManager, deleteDialog.tag) + } + + binding.SendCardView.setOnClickListener { + if (binding.commentEt.text.toString().isNotBlank()) { + viewModel.createComment() + } + binding.commentEt.setText("") + viewModel.replyCommentParentId.value = 0 + } + + + binding.editBtn.setOnClickListener { + + } + } + + private fun showReportBtn() { + binding.dotBtn.setOnClickListener { + if (!isShowMenu) { + binding.reportBtn.bringToFront() + binding.reportBtn.visibility = View.VISIBLE + isShowMenu = true + } else { + binding.reportBtn.visibility = View.GONE + isShowMenu = false + } + } + } + + private fun showWriterMenu() { + binding.dotBtn.setOnClickListener { + if (!isShowMenu) { + binding.communityMenu.bringToFront() + binding.communityMenu.visibility = View.VISIBLE + isShowMenu = true + } else { + binding.communityMenu.visibility = View.GONE + isShowMenu = false + } + } + } + + override fun initObserver() { + with(lifecycleScope) { + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.postId.collect { + if (it != 0L) { + viewModel.readCommunication(it) + } + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.postContent.collect { response -> + with(binding) { + writerTv.text = response.writer + titleTv.text = response.title + contentT.text = response.content + + + Log.d("image", response.imageUrls.toString()) + imageAdapter.submitList(response.imageUrls.map { url -> + ImageUrl(url.imageUrl) + }) + if (response.writer == " 1") { + communityMenu.bringToFront() + } + likeT.text = response.likeCount.toString() + bookmarkT.text = response.scrapCount.toString() + commitT.text = response.commentCount.toString() + + if (response.writer == TtoklipApplication.prefs.getString( + "nickname", + "" + ) + ) { + showWriterMenu() + } else { + showReportBtn() + } + } + } + } + } + + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.comments.collect { + val list = it.map { it -> + NewsCommentResponse( + it.commentContent, + it.commentId.toInt(), + it.parentId.toInt(), + it.writer, + it.writtenTime + ) + } + commentRVA.submitList(list) + } + } + } + + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.replyCommentParentId.collect { id -> + if (id == 0) { + binding.replyT.text = "" + } else { + binding.replyT.text = "@${id}" + } + } + } + } + + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.toast.collect { + Toast.makeText(this@ReadCommunicationActivity, it, Toast.LENGTH_SHORT) + .show() + } + } + } + } + } + + override fun dispatchTouchEvent(event: MotionEvent?): Boolean { + if (event?.action == MotionEvent.ACTION_DOWN) { + val v = currentFocus + if (v is EditText) { + val outRect = Rect() + v.getGlobalVisibleRect(outRect) + if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) { + v.clearFocus() + val imm: InputMethodManager = + getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(v.getWindowToken(), 0) + } + } + } + return super.dispatchTouchEvent(event) + } + + override fun onClick(imageUrl: String) { + val images = imageAdapter.currentList.filterIsInstance().map { it.imageUrl } + .toTypedArray() + Log.d("images", images.toString()) + val intent = Intent(this, ImageViewActivity::class.java) + intent.putExtra("images", images) + startActivity(intent) + } + + companion object { + const val COMMUNICATION = "postId" + fun newIntent(context: Context, id: Long) = + Intent(context, ReadCommunicationActivity::class.java).apply { + putExtra(COMMUNICATION, id) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/read/ReadCommunicationViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/read/ReadCommunicationViewModel.kt new file mode 100644 index 00000000..9831b3ff --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/read/ReadCommunicationViewModel.kt @@ -0,0 +1,36 @@ +package com.umc.ttoklip.presentation.hometown.communication.read + +import com.umc.ttoklip.data.model.town.ReportRequest +import com.umc.ttoklip.data.model.town.ViewCommunicationResponse +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.StateFlow + +interface ReadCommunicationViewModel { + val postId: StateFlow + val postContent: StateFlow + val like: StateFlow + val scrap: StateFlow + val replyCommentParentId : MutableStateFlow + val commentContent: MutableStateFlow + val comments: StateFlow> + val toast: SharedFlow + val toastEvent: SharedFlow + + sealed class ToastEvent(){ + object SuccessReportEvent: ToastEvent() + object FailReportEvent: ToastEvent() + } + + fun eventToast(event: ToastEvent) + fun savePostId(postId: Long) + fun readCommunication(postId: Long) + + fun deleteCommunication() + fun changeScrap() + fun changeLike() + fun reportPost(reportRequest: ReportRequest) + fun reportComment(commentId: Long, reportRequest: com.umc.ttoklip.data.model.honeytip.request.ReportRequest) + fun deleteComment(commentId: Long) + fun createComment() +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/read/ReadCommunicationViewModelImpl.kt similarity index 55% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationViewModelImpl.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/read/ReadCommunicationViewModelImpl.kt index a0005481..287235ca 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadCommunicationViewModelImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/read/ReadCommunicationViewModelImpl.kt @@ -1,4 +1,4 @@ -package com.umc.ttoklip.presentation.hometown +package com.umc.ttoklip.presentation.hometown.communication.read import android.util.Log import androidx.lifecycle.ViewModel @@ -9,9 +9,12 @@ import com.umc.ttoklip.data.model.town.ReportRequest import com.umc.ttoklip.data.model.town.ViewCommunicationResponse import com.umc.ttoklip.data.repository.town.ReadCommsRepository import com.umc.ttoklip.module.onError +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 +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import javax.inject.Inject @@ -54,6 +57,27 @@ class ReadCommunicationViewModelImpl @Inject constructor( override val scrap: StateFlow get() = _scrap + override val replyCommentParentId = MutableStateFlow(0) + override val commentContent = MutableStateFlow("") + + private val _comments = MutableStateFlow(listOf()) + override val comments: StateFlow> + get() = _comments + + private val _toast = MutableSharedFlow() + override val toast: SharedFlow + get() = _toast + + private val _toastEvent = MutableSharedFlow() + override val toastEvent: SharedFlow + get() = _toastEvent + + override fun eventToast(event: ReadCommunicationViewModel.ToastEvent) { + viewModelScope.launch { + _toastEvent.emit(event) + } + } + override fun savePostId(postId: Long) { _postId.value = postId } @@ -64,22 +88,38 @@ class ReadCommunicationViewModelImpl @Inject constructor( _postContent.value = it _like.value = it.likedByCurrentUser _scrap.value = it.scrapedByCurrentUser + _comments.value = it.commentResponses }.onError { } } } + override fun deleteCommunication() { + viewModelScope.launch { + repository.deleteComms(_postId.value).onSuccess { + _toast.emit("게시글 삭제가 완료되었습니다.") + } + } + } + override fun changeScrap() { Log.d("change", "스크랩") _scrap.value = _scrap.value.not() + Log.d("scrap", scrap.value.toString()) viewModelScope.launch { if (_scrap.value) { repository.addCommsScrap(postId.value).onSuccess { + _postContent.emit(_postContent.value.copy().also { + it.scrapCount += 1 + }) } } else { repository.cancelCommsScrap(postId.value).onSuccess { Log.d("change", "스크랩") + _postContent.emit(_postContent.value.copy().also { + it.scrapCount -= 1 + }) } } } @@ -91,10 +131,15 @@ class ReadCommunicationViewModelImpl @Inject constructor( viewModelScope.launch { if (_like.value) { repository.addCommsLike(postId.value).onSuccess { + _postContent.emit(_postContent.value.copy().also { + it.likeCount += 1 + }) } } else { repository.cancelCommsLike(postId.value).onSuccess { - Log.d("change", "좋아요") + _postContent.emit(_postContent.value.copy().also { + it.likeCount -= 1 + }) } } } @@ -103,27 +148,46 @@ class ReadCommunicationViewModelImpl @Inject constructor( override fun reportPost(reportRequest: ReportRequest) { viewModelScope.launch { if (postId.value != 0L) { - repository.reportComms(postId.value, reportRequest) + repository.reportComms(postId.value, reportRequest).onSuccess { + Log.d("report", it.toString()) + _toast.emit("게시글 신고가 완료되었습니다.") + }.onFail { + _toast.emit("게시글 신고 타입을 설정해주세요.") + } } } } - override fun reportComment(commentId: Long, reportRequest: ReportRequest) { + override fun reportComment( + commentId: Long, + reportRequest: com.umc.ttoklip.data.model.honeytip.request.ReportRequest + ) { viewModelScope.launch { - repository.reportCommsComment(commentId, reportRequest) + repository.reportCommsComment(commentId, reportRequest).onSuccess { + _toast.emit("댓글 신고가 완료되었습니다.") + }.onFail { + _toast.emit("댓글 신고 타입을 설정해주세요.") + } } } override fun deleteComment(commentId: Long) { viewModelScope.launch { - repository.deleteCommsComment(commentId) + repository.deleteCommsComment(commentId).onSuccess { + readCommunication(postId.value) + } } } - override fun createComment(body: CreateCommentRequest) { + override fun createComment() { viewModelScope.launch { if (postId.value != 0L) { - repository.createCommsComment(postId.value, body) + repository.createCommsComment( + postId.value, + CreateCommentRequest(commentContent.value, replyCommentParentId.value.toLong()) + ).onSuccess { + readCommunication(postId.value) + } } } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteCommunicationActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/write/WriteCommunicationActivity.kt similarity index 89% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteCommunicationActivity.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/write/WriteCommunicationActivity.kt index 25c84e13..76004768 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteCommunicationActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/write/WriteCommunicationActivity.kt @@ -1,143 +1,136 @@ -package com.umc.ttoklip.presentation.hometown - -import android.content.Context -import android.graphics.Rect -import android.net.Uri -import android.util.Log -import android.view.MotionEvent -import android.view.View -import android.view.inputmethod.InputMethodManager -import android.widget.EditText -import androidx.activity.result.PickVisualMediaRequest -import androidx.activity.result.contract.ActivityResultContracts -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.databinding.ActivityWriteCommunicationBinding -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.dialog.ImageDialogFragment -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch - -@AndroidEntryPoint -class WriteCommunicationActivity : - BaseActivity(R.layout.activity_write_communication) { - private val imageAdapter by lazy { - ImageRVA(null) - } - private val viewModel: WriteCommunicationViewModel by viewModels() - private val pickMultipleMedia = registerForActivityResult( - ActivityResultContracts.PickMultipleVisualMedia( - 100 - ) - ) { uris -> - if (uris.isNotEmpty()) { - updateImages(uris) - } else { - Log.d("PhotoPicker", "No media selected") - } - } - - override fun initView() { - binding.vm = viewModel as WriteCommunicationViewModelImpl - initImageRVA() - addImage() - - binding.backBtn.setOnClickListener { - finish() - } - } - - override fun initObserver() { - with(lifecycleScope) { - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.doneButtonActivated.collect { - binding.writeDoneBtn.isEnabled = it - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.title.collect { - viewModel.checkDone() - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.content.collect { - viewModel.checkDone() - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.content.collect { - viewModel.checkDone() - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.images.collect { - Log.d("uri image", it.toString()) - imageAdapter.submitList(it.toList()) - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.closePage.collect { - Log.d("close page", it.toString()) - if (it) finish() - } - } - } - } - } - - private fun initImageRVA() { - binding.imageRv.adapter = imageAdapter - } - - private fun addImage() { - binding.addImageBtn.setOnClickListener { - val imageDialog = ImageDialogFragment() - imageDialog.setDialogClickListener(object : ImageDialogFragment.DialogClickListener { - override fun onClick() { - binding.imageRv.visibility = View.VISIBLE - pickMultipleMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)) - } - }) - imageDialog.show(supportFragmentManager, imageDialog.tag) - } - } - - private fun updateImages(uriList: List) { - Log.d("uri", uriList.toString()) - val images = uriList.map { Image(it) } - viewModel.addImages(images) - } - - override fun dispatchTouchEvent(event: MotionEvent?): Boolean { - if (event?.action == MotionEvent.ACTION_DOWN) { - val v = currentFocus - if (v is EditText) { - val outRect = Rect() - v.getGlobalVisibleRect(outRect) - if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) { - v.clearFocus() - val imm: InputMethodManager = - getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(v.getWindowToken(), 0) - } - } - } - return super.dispatchTouchEvent(event) - } +package com.umc.ttoklip.presentation.hometown.communication.write + +import android.content.Context +import android.graphics.Rect +import android.net.Uri +import android.util.Log +import android.view.MotionEvent +import android.view.View +import android.view.inputmethod.InputMethodManager +import android.widget.EditText +import androidx.activity.result.PickVisualMediaRequest +import androidx.activity.result.contract.ActivityResultContracts +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.databinding.ActivityWriteCommunicationBinding +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.dialog.ImageDialogFragment +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class WriteCommunicationActivity : + BaseActivity(R.layout.activity_write_communication) { + private val imageAdapter by lazy { + ImageRVA(this, null) + } + private val viewModel: WriteCommunicationViewModel by viewModels() + private val pickMultipleMedia = registerForActivityResult( + ActivityResultContracts.PickMultipleVisualMedia( + 100 + ) + ) { uris -> + if (uris.isNotEmpty()) { + updateImages(uris) + } else { + Log.d("PhotoPicker", "No media selected") + } + } + + override fun initView() { + binding.vm = viewModel as WriteCommunicationViewModelImpl + initImageRVA() + addImage() + + binding.backBtn.setOnClickListener { + finish() + } + } + + override fun initObserver() { + with(lifecycleScope) { + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.doneButtonActivated.collect { + binding.writeDoneBtn.isEnabled = it + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.title.collect { + viewModel.checkDone() + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.content.collect { + viewModel.checkDone() + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.images.collect { + Log.d("uri image", it.toString()) + imageAdapter.submitList(it.toList()) + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.closePage.collect { + Log.d("close page", it.toString()) + if (it) finish() + } + } + } + } + } + + private fun initImageRVA() { + binding.imageRv.adapter = imageAdapter + } + + private fun addImage() { + binding.addImageBtn.setOnClickListener { + val imageDialog = ImageDialogFragment() + imageDialog.setDialogClickListener(object : ImageDialogFragment.DialogClickListener { + override fun onClick() { + binding.imageRv.visibility = View.VISIBLE + pickMultipleMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)) + } + }) + imageDialog.show(supportFragmentManager, imageDialog.tag) + } + } + + private fun updateImages(uriList: List) { + Log.d("uri", uriList.toString()) + val images = uriList.map { Image(it, "") } + viewModel.addImages(images) + } + + override fun dispatchTouchEvent(event: MotionEvent?): Boolean { + if (event?.action == MotionEvent.ACTION_DOWN) { + val v = currentFocus + if (v is EditText) { + val outRect = Rect() + v.getGlobalVisibleRect(outRect) + if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) { + v.clearFocus() + val imm: InputMethodManager = + getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(v.getWindowToken(), 0) + } + } + } + return super.dispatchTouchEvent(event) + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteCommunicationViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/write/WriteCommunicationViewModel.kt similarity index 86% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteCommunicationViewModel.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/write/WriteCommunicationViewModel.kt index ca2389e7..6d128850 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteCommunicationViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/write/WriteCommunicationViewModel.kt @@ -1,4 +1,4 @@ -package com.umc.ttoklip.presentation.hometown +package com.umc.ttoklip.presentation.hometown.communication.write import com.umc.ttoklip.presentation.honeytip.adapter.Image import kotlinx.coroutines.flow.StateFlow diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteCommunicationViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/write/WriteCommunicationViewModelImpl.kt similarity index 97% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteCommunicationViewModelImpl.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/write/WriteCommunicationViewModelImpl.kt index 33b2af65..dfb3f967 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteCommunicationViewModelImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/communication/write/WriteCommunicationViewModelImpl.kt @@ -1,4 +1,4 @@ -package com.umc.ttoklip.presentation.hometown +package com.umc.ttoklip.presentation.hometown.communication.write import android.content.Context import android.util.Log diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/TogetherActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/TogetherActivity.kt similarity index 96% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/TogetherActivity.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/together/TogetherActivity.kt index 6cf90c40..9f31d893 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/TogetherActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/TogetherActivity.kt @@ -1,166 +1,168 @@ -package com.umc.ttoklip.presentation.hometown - -import android.content.Intent -import android.util.Log -import androidx.activity.viewModels -import androidx.core.view.isGone -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle -import androidx.recyclerview.widget.LinearLayoutManager -import com.umc.ttoklip.R -import com.umc.ttoklip.data.model.town.Togethers -import com.umc.ttoklip.databinding.ActivityTogetherBinding -import com.umc.ttoklip.presentation.alarm.AlarmActivity -import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.hometown.dialog.TogetherBottomSheetDialogFragment -import com.umc.ttoklip.presentation.mypage.adapter.OnTogetherItemClickListener -import com.umc.ttoklip.presentation.mypage.adapter.TransactionAdapter -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch - -@AndroidEntryPoint -class TogetherActivity : BaseActivity(R.layout.activity_together), - OnTogetherItemClickListener { - private val viewModel: TogetherViewModel by viewModels() - private val adapter by lazy { - TransactionAdapter(this, this) - } - - override fun initView() { - binding.vm = viewModel - binding.writeFab.setOnClickListener { - val intent = Intent(this, WriteTogetherActivity::class.java) - startActivity(intent) - } - binding.backBtn.setOnClickListener { - finish() - } - viewModel.get() - - binding.noticeBtn.setOnClickListener { - startActivity(AlarmActivity.newIntent(this)) - } - - binding.togetherRv.adapter = adapter - binding.togetherRv.layoutManager = LinearLayoutManager(this) - } - - override fun onStart() { - super.onStart() - Log.d("start", "start") - } - override fun onResume() { - super.onResume() - Log.d("resume", "resume") - viewModel.get() - } - - override fun initObserver() { - with(lifecycleScope) { - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.showDialog.collect { - if (it) { - val sheet = TogetherBottomSheetDialogFragment { filter -> - viewModel.getFilters(filter[0], filter[1]) - } - sheet.show(supportFragmentManager, sheet.tag) - } - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.mainData.collect { - adapter.submitList(it.carts) - } - } - } - - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.filterRequiredAmount.collect { - binding.requiredAmount.isGone = false - when (it) { - 1L -> { - binding.requiredAmount.text = "10,000" - } - - 2L -> { - binding.requiredAmount.text = "20,000" - } - - 3L -> { - binding.requiredAmount.text = "30,000" - } - - 4L -> { - binding.requiredAmount.text = "40,000" - } - - 5L -> { - binding.requiredAmount.text = "50,000 이상" - } - - else -> { - binding.requiredAmount.isGone = true - } - } - } - } - } - - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.filterMaxMember.collect { - binding.maxMemberSizeTv.isGone = false - when (it) { - 1L -> { - binding.maxMemberSizeTv.text = "2~4" - } - - 2L -> { - binding.maxMemberSizeTv.text = "5~7" - } - - 3L -> { - binding.maxMemberSizeTv.text = "8~10" - } - - 4L -> { - binding.maxMemberSizeTv.text = "11~13" - } - - 5L -> { - binding.maxMemberSizeTv.text = "14~17" - } - - 6L -> { - binding.maxMemberSizeTv.text = "18~20" - } - - else -> { - binding.maxMemberSizeTv.isGone = true - } - } - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.togethers.collect { - adapter.submitList(it) - } - } - } - } - } - - override fun onClick(together: Togethers) { - val intent = Intent(this, ReadTogetherActivity::class.java) - intent.putExtra("postId", together.id) - startActivity(intent) - } - +package com.umc.ttoklip.presentation.hometown.together + +import android.content.Intent +import android.util.Log +import androidx.activity.viewModels +import androidx.core.view.isGone +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import androidx.recyclerview.widget.LinearLayoutManager +import com.umc.ttoklip.R +import com.umc.ttoklip.data.model.town.Togethers +import com.umc.ttoklip.databinding.ActivityTogetherBinding +import com.umc.ttoklip.presentation.alarm.AlarmActivity +import com.umc.ttoklip.presentation.base.BaseActivity +import com.umc.ttoklip.presentation.hometown.dialog.TogetherBottomSheetDialogFragment +import com.umc.ttoklip.presentation.hometown.together.read.ReadTogetherActivity +import com.umc.ttoklip.presentation.hometown.together.write.WriteTogetherActivity +import com.umc.ttoklip.presentation.mypage.adapter.OnTogetherItemClickListener +import com.umc.ttoklip.presentation.mypage.adapter.TransactionAdapter +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class TogetherActivity : BaseActivity(R.layout.activity_together), + OnTogetherItemClickListener { + private val viewModel: TogetherViewModel by viewModels() + private val adapter by lazy { + TransactionAdapter(this, this) + } + + override fun initView() { + binding.vm = viewModel + binding.writeFab.setOnClickListener { + val intent = Intent(this, WriteTogetherActivity::class.java) + startActivity(intent) + } + binding.backBtn.setOnClickListener { + finish() + } + viewModel.get() + + binding.noticeBtn.setOnClickListener { + startActivity(AlarmActivity.newIntent(this)) + } + + binding.togetherRv.adapter = adapter + binding.togetherRv.layoutManager = LinearLayoutManager(this) + } + + override fun onStart() { + super.onStart() + Log.d("start", "start") + } + override fun onResume() { + super.onResume() + Log.d("resume", "resume") + viewModel.get() + } + + override fun initObserver() { + with(lifecycleScope) { + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.showDialog.collect { + if (it) { + val sheet = TogetherBottomSheetDialogFragment { filter -> + viewModel.getFilters(filter[0], filter[1]) + } + sheet.show(supportFragmentManager, sheet.tag) + } + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.mainData.collect { + adapter.submitList(it.carts) + } + } + } + + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.filterRequiredAmount.collect { + binding.requiredAmount.isGone = false + when (it) { + 1L -> { + binding.requiredAmount.text = "10,000" + } + + 2L -> { + binding.requiredAmount.text = "20,000" + } + + 3L -> { + binding.requiredAmount.text = "30,000" + } + + 4L -> { + binding.requiredAmount.text = "40,000" + } + + 5L -> { + binding.requiredAmount.text = "50,000 이상" + } + + else -> { + binding.requiredAmount.isGone = true + } + } + } + } + } + + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.filterMaxMember.collect { + binding.maxMemberSizeTv.isGone = false + when (it) { + 1L -> { + binding.maxMemberSizeTv.text = "2~4" + } + + 2L -> { + binding.maxMemberSizeTv.text = "5~7" + } + + 3L -> { + binding.maxMemberSizeTv.text = "8~10" + } + + 4L -> { + binding.maxMemberSizeTv.text = "11~13" + } + + 5L -> { + binding.maxMemberSizeTv.text = "14~17" + } + + 6L -> { + binding.maxMemberSizeTv.text = "18~20" + } + + else -> { + binding.maxMemberSizeTv.isGone = true + } + } + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.togethers.collect { + adapter.submitList(it) + } + } + } + } + } + + override fun onClick(together: Togethers) { + val intent = Intent(this, ReadTogetherActivity::class.java) + intent.putExtra("postId", together.id) + startActivity(intent) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/TogetherViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/TogetherViewModel.kt similarity index 83% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/TogetherViewModel.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/together/TogetherViewModel.kt index 4ed79a28..f14e2049 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/TogetherViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/TogetherViewModel.kt @@ -1,4 +1,4 @@ -package com.umc.ttoklip.presentation.hometown +package com.umc.ttoklip.presentation.hometown.together import com.umc.ttoklip.data.model.town.Togethers import com.umc.ttoklip.data.model.town.TogethersResponse @@ -11,7 +11,7 @@ interface TogetherViewModel { val showDialog: SharedFlow val page: StateFlow val togethers: StateFlow> - val mainData : StateFlow + val mainData : SharedFlow fun onFilterClick() diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/TogetherViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/TogetherViewModelImpl.kt similarity index 92% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/TogetherViewModelImpl.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/together/TogetherViewModelImpl.kt index 5f3b9b76..bf1f5f9a 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/TogetherViewModelImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/TogetherViewModelImpl.kt @@ -1,146 +1,146 @@ -package com.umc.ttoklip.presentation.hometown - -import android.util.Log -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.umc.ttoklip.data.model.town.Togethers -import com.umc.ttoklip.data.model.town.TogethersResponse -import com.umc.ttoklip.data.repository.town.MainTogethersRepository -import com.umc.ttoklip.module.onError -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 -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.launch -import javax.inject.Inject - -@HiltViewModel -class TogetherViewModelImpl @Inject constructor(private val repository: MainTogethersRepository) : - ViewModel(), TogetherViewModel { - private val _filterRequiredAmount = MutableStateFlow(0L) - override val filterRequiredAmount: StateFlow - get() = _filterRequiredAmount - - private val _filterMaxMember = MutableStateFlow(0L) - override val filterMaxMember: StateFlow - get() = _filterMaxMember - - private val _showDialog = MutableSharedFlow() - override val showDialog: SharedFlow - get() = _showDialog - - private val _page: MutableStateFlow = MutableStateFlow(0L) - override val page: StateFlow - get() = _page - - private val _togethers: MutableStateFlow> = MutableStateFlow(emptyList()) - override val togethers: StateFlow> - get() = _togethers - - private val _mainData = MutableStateFlow(TogethersResponse()) - override val mainData: StateFlow - get() = _mainData - - override fun onFilterClick() { - viewModelScope.launch { - _showDialog.emit(true) - } - } - - override fun get() { - viewModelScope.launch { - try { - repository.getTogethers(0,1,10000000000,1,20) - .onSuccess { - _mainData.emit(it) - Log.d("emit", "emit") - }.onFail { - - }.onException { - throw it - } - } catch (e: Exception) { - e.printStackTrace() - Log.d("예외", "$e") - } - } - } - - override fun getFilters(requiredAmount: Long, maxMember: Long) { - viewModelScope.launch { - _filterRequiredAmount.value = requiredAmount - _filterMaxMember.value = maxMember - var require = when (requiredAmount) { - 1L -> { - 10000L - } - - 2L -> { - 20000L - } - - 3L -> { - 30000L - } - - 4L -> { - 40000L - } - - 5L -> { - 50000L - } - - else -> { - 0L - } - } - var min = 1L - var max = 20L - when (maxMember) { - 1L -> { - min = 2L - max = 4L - } - - 2L -> { - min = 5L - max = 7L - } - - 3L -> { - min = 8L - max = 10L - } - - 4L -> { - min = 11L - max = 13L - } - - 5L -> { - min = 14L - max = 17L - } - - 6L -> { - min = 18L - max = 20L - } - - else -> { - - } - } - repository.getTogethers(page.value, require, 10000000000, min, max).onSuccess { - _togethers.value = it.carts - }.onError { - Log.d("error", it.printStackTrace().toString()) - } - } - } +package com.umc.ttoklip.presentation.hometown.together + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.town.Togethers +import com.umc.ttoklip.data.model.town.TogethersResponse +import com.umc.ttoklip.data.repository.town.MainTogethersRepository +import com.umc.ttoklip.module.onError +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 +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class TogetherViewModelImpl @Inject constructor(private val repository: MainTogethersRepository) : + ViewModel(), TogetherViewModel { + private val _filterRequiredAmount = MutableStateFlow(0L) + override val filterRequiredAmount: StateFlow + get() = _filterRequiredAmount + + private val _filterMaxMember = MutableStateFlow(0L) + override val filterMaxMember: StateFlow + get() = _filterMaxMember + + private val _showDialog = MutableSharedFlow() + override val showDialog: SharedFlow + get() = _showDialog + + private val _page: MutableStateFlow = MutableStateFlow(0L) + override val page: StateFlow + get() = _page + + private val _togethers: MutableStateFlow> = MutableStateFlow(emptyList()) + override val togethers: StateFlow> + get() = _togethers + + private val _mainData = MutableSharedFlow() + override val mainData: SharedFlow + get() = _mainData + + override fun onFilterClick() { + viewModelScope.launch { + _showDialog.emit(true) + } + } + + override fun get() { + viewModelScope.launch { + try { + repository.getTogethers(0,1,10000000000,1,20) + .onSuccess { + _mainData.emit(it) + Log.d("emit", "emit") + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + + override fun getFilters(requiredAmount: Long, maxMember: Long) { + viewModelScope.launch { + _filterRequiredAmount.value = requiredAmount + _filterMaxMember.value = maxMember + var require = when (requiredAmount) { + 1L -> { + 10000L + } + + 2L -> { + 20000L + } + + 3L -> { + 30000L + } + + 4L -> { + 40000L + } + + 5L -> { + 50000L + } + + else -> { + 0L + } + } + var min = 1L + var max = 20L + when (maxMember) { + 1L -> { + min = 2L + max = 4L + } + + 2L -> { + min = 5L + max = 7L + } + + 3L -> { + min = 8L + max = 10L + } + + 4L -> { + min = 11L + max = 13L + } + + 5L -> { + min = 14L + max = 17L + } + + 6L -> { + min = 18L + max = 20L + } + + else -> { + + } + } + repository.getTogethers(page.value, require, 10000000000, min, max).onSuccess { + _togethers.value = it.carts + }.onError { + Log.d("error", it.printStackTrace().toString()) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/read/ReadTogetherActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/read/ReadTogetherActivity.kt new file mode 100644 index 00000000..5d792cff --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/read/ReadTogetherActivity.kt @@ -0,0 +1,322 @@ +package com.umc.ttoklip.presentation.hometown.together.read + +import android.content.Context +import android.content.Intent +import android.graphics.Rect +import android.icu.text.DecimalFormat +import android.text.SpannableString +import android.text.style.ForegroundColorSpan +import android.util.Log +import android.view.MotionEvent +import android.view.inputmethod.InputMethodManager +import android.widget.EditText +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 +import com.umc.ttoklip.R +import com.umc.ttoklip.TtoklipApplication +import com.umc.ttoklip.data.model.honeytip.ImageUrl +import com.umc.ttoklip.data.model.honeytip.request.ReportRequest +import com.umc.ttoklip.data.model.news.comment.NewsCommentResponse +import com.umc.ttoklip.data.model.town.CreateCommentRequest +import com.umc.ttoklip.databinding.ActivityReadTogetherBinding +import com.umc.ttoklip.presentation.base.BaseActivity +import com.umc.ttoklip.presentation.hometown.adapter.TownCommentAdapter +import com.umc.ttoklip.presentation.honeytip.ImageViewActivity +import com.umc.ttoklip.presentation.honeytip.adapter.OnReadImageClickListener +import com.umc.ttoklip.presentation.honeytip.adapter.ReadImageRVA +import com.umc.ttoklip.presentation.dialog.DeleteDialogFragment +import com.umc.ttoklip.presentation.dialog.FinishCartDialogFragment +import com.umc.ttoklip.presentation.dialog.ReportDialogFragment +import com.umc.ttoklip.presentation.hometown.dialog.TogetherDialog +import com.umc.ttoklip.presentation.honeytip.read.ReadHoneyTipActivity +import com.umc.ttoklip.presentation.news.adapter.CommentRVA +import com.umc.ttoklip.presentation.otheruser.OtherUserActivity +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class ReadTogetherActivity : + BaseActivity(R.layout.activity_read_together), + OnReadImageClickListener{ + private val viewModel: ReadTogetherViewModel by viewModels() + private val imageAdapter: ReadImageRVA by lazy { + ReadImageRVA(this, this@ReadTogetherActivity) + } + private val commentRVA by lazy { + CommentRVA({ id -> + viewModel.replyCommentParentId.value = id + }, { id, myComment -> + Log.d("mycomment", myComment.toString()) + if (myComment) { + val deleteDialog = DeleteDialogFragment() + deleteDialog.setDialogClickListener(object : + DeleteDialogFragment.DialogClickListener { + override fun onClick() { + viewModel.deleteComment(id.toLong()) + } + }) + deleteDialog.show(supportFragmentManager, deleteDialog.tag) + } else { + val reportDialog = ReportDialogFragment() + reportDialog.setDialogClickListener(object : ReportDialogFragment.DialogClickListener{ + override fun onClick(type: String, content: String) { + viewModel.reportComment( + id.toLong(), + com.umc.ttoklip.data.model.town.ReportRequest( + content = content, + reportType = type + ) + ) + } + }) + reportDialog.show(supportFragmentManager, reportDialog.tag) + } + }, { nick -> + startActivity(OtherUserActivity.newIntent(this, nick)) + }) + } + private var postId = 0L + private var isWriter = false + + override fun initView() { + binding.imageRv.apply { + itemAnimator = null + adapter = imageAdapter + } + binding.commentRv.adapter = commentRVA + binding.replyT.setOnClickListener { + viewModel.replyCommentParentId.value = 0 + } + binding.vm = viewModel + postId = intent.getLongExtra("postId", 0) + viewModel.savePostId(postId) + + binding.backBtn.setOnClickListener { + finish() + } + + binding.dotBtn.setOnClickListener { + if (isWriter) { + binding.editBtn.bringToFront() + binding.editBtn.isVisible = binding.editBtn.isVisible.not() + } else { + binding.reportBtn.bringToFront() + binding.reportBtn.isVisible = binding.reportBtn.isVisible.not() + } + } + + binding.reportBtn.setOnClickListener { + val reportDialog = ReportDialogFragment() + reportDialog.setDialogClickListener(object : ReportDialogFragment.DialogClickListener { + override fun onClick(type: String, content: String) { + viewModel.reportPost( + com.umc.ttoklip.data.model.town.ReportRequest( + content = content, + reportType = type + ) + ) + } + + }) + reportDialog.show(supportFragmentManager, reportDialog.tag) + } + + + binding.SendCardView.setOnClickListener { + if (binding.commentEt.text.toString().isNotBlank()) { + viewModel.createComment() + } + binding.commentEt.setText("") + viewModel.replyCommentParentId.value = 0 + } + + binding.ownerCheckBtn.setOnClickListener { + viewModel.fetchParticipantsCount() + } + + binding.ownerJoinBtn.setOnClickListener { + val finishCartDialog = FinishCartDialogFragment() + finishCartDialog.setDialogClickListener(object : FinishCartDialogFragment.DialogClickListener{ + override fun onClick() { + viewModel.patchPostStatus("COMPLETED") + } + }) + finishCartDialog.show(supportFragmentManager, finishCartDialog.tag) + } + + binding.joinBtn.setOnClickListener { + val joinDialog = TogetherDialog() + joinDialog.setDialogClickListener(object : TogetherDialog.TogetherDialogClickListener{ + override fun onClick() { + viewModel.setJoinState(true) + viewModel.joinTogether() + } + }) + joinDialog.show(supportFragmentManager, joinDialog.tag) + } + + binding.joinCancelBtn.setOnClickListener { + viewModel.setJoinState(false) + viewModel.cancelTogether() + } + + } + + override fun initObserver() { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.joinState.collect { + /*if (it.not()) { + binding.joinBtn.background = + getDrawable(R.drawable.rectangle_corner_10_strok_1_gray40) +// binding.joinBtn.text = getString(R.string.cancel_join) + } else { + binding.joinBtn.background = + getDrawable(R.drawable.yellow_btn_background) +// binding.joinBtn.text = getString(R.string.join_together) + }*/ + } + } + } + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.postId.collect { + viewModel.readTogether(it) + } + } + } + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.postContent.collect { response -> + with(binding) { + writerTv.text = response.writer + titleT.text = response.title + contentT.text = response.content + totalPriceTv.text = AMOUNT_FORMAT.format(response.totalPrice).toString() + maxMemberTv.text = response.partyMax.toString() + tradingPlaceTv.text = response.location + openChatLinkTv.text = response.chatUrl + + imageAdapter.submitList(response.imageUrls.map { url -> + ImageUrl( + imageUrl = url.imageUrl + ) + }) + val spannableAmount = + SpannableString( + getString( + R.string.join_stat_format, + response.partyCnt, + response.partyMax + ) + ) + spannableAmount.setSpan( + ForegroundColorSpan(getColor(R.color.blue)), + AMOUNT_STRING_START, + response.partyCnt.toString().length + AMOUNT_STRING_LENGTH, + SPANNABLE_FLAG_ZERO + ) + binding.currentJoinStatTv.text = spannableAmount + } + } + } + } + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.writer.collect { + val writer = TtoklipApplication.prefs.getString("nickname", "") + viewModel.checkWriter(writer) + } + } + } + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.isWriter.collect { + isWriter = it + } + } + } + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.toast.collect { + Toast.makeText(this@ReadTogetherActivity, it, Toast.LENGTH_SHORT) + .show() + } + } + } + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.comments.collect { + val list = it.map { it -> + NewsCommentResponse( + it.commentContent, + it.commentId.toInt(), + it.parentId.toInt(), + it.writer, + it.writtenTime + ) + } + commentRVA.submitList(list) + } + } + } + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.replyCommentParentId.collect { id -> + if (id == 0) { + binding.replyT.text = "" + } else { + binding.replyT.text = "@${id}" + } + } + } + } + } + + + override fun dispatchTouchEvent(event: MotionEvent?): Boolean { + if (event?.action == MotionEvent.ACTION_DOWN) { + val v = currentFocus + if (v is EditText) { + val outRect = Rect() + v.getGlobalVisibleRect(outRect) + if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) { + v.clearFocus() + val imm: InputMethodManager = + getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(v.getWindowToken(), 0) + } + } + } + return super.dispatchTouchEvent(event) + } + + companion object { + private const val AMOUNT_STRING_START = 0 + private const val SPANNABLE_FLAG_ZERO = 0 + private const val AMOUNT_STRING_LENGTH = 1 + private val AMOUNT_FORMAT = DecimalFormat("#,###") + fun newIntent(context: Context, id: Long) = + Intent(context, ReadTogetherActivity::class.java).apply { + putExtra("postId", id) + } + } + + override fun onClick(imageUrl: String) { + val images = imageAdapter.currentList.filterIsInstance().map { it.imageUrl } + .toTypedArray() + Log.d("images", images.toString()) + val intent = Intent(this, ImageViewActivity::class.java) + intent.putExtra("images", images) + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/read/ReadTogetherViewModel.kt similarity index 53% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherViewModel.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/together/read/ReadTogetherViewModel.kt index 585a0020..07a4c01d 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/read/ReadTogetherViewModel.kt @@ -1,24 +1,39 @@ -package com.umc.ttoklip.presentation.hometown +package com.umc.ttoklip.presentation.hometown.together.read import com.umc.ttoklip.data.model.town.CreateCommentRequest import com.umc.ttoklip.data.model.town.ReportRequest import com.umc.ttoklip.data.model.town.ViewTogetherResponse +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow interface ReadTogetherViewModel { val joinState: StateFlow val deadlineState: StateFlow - val isOwner: StateFlow + val isWriter: StateFlow val postId: StateFlow + val writer: StateFlow + val toast: SharedFlow val postContent: StateFlow + val replyCommentParentId : MutableStateFlow + val comments: StateFlow> + val commentContent: MutableStateFlow fun joinBtnClick() + + fun setJoinState(joinState: Boolean) fun savePostId(postId: Long) + + fun checkWriter(writer: String) fun readTogether(postId: Long) fun reportPost(reportRequest: ReportRequest) fun reportComment(commentId: Long, reportRequest: ReportRequest) fun deleteComment(commentId: Long) - fun createComment(body: CreateCommentRequest) + fun createComment() fun joinTogether() fun cancelTogether() + + fun fetchParticipantsCount() + + fun patchPostStatus(status: String) } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/read/ReadTogetherViewModelImpl.kt similarity index 52% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherViewModelImpl.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/together/read/ReadTogetherViewModelImpl.kt index ac4e6b6b..58b5bce0 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/ReadTogetherViewModelImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/read/ReadTogetherViewModelImpl.kt @@ -1,15 +1,21 @@ -package com.umc.ttoklip.presentation.hometown +package com.umc.ttoklip.presentation.hometown.together.read +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.town.CommentResponse import com.umc.ttoklip.data.model.town.CreateCommentRequest +import com.umc.ttoklip.data.model.town.PatchCartStatusRequest import com.umc.ttoklip.data.model.town.ReportRequest import com.umc.ttoklip.data.model.town.ViewTogetherResponse import com.umc.ttoklip.data.repository.town.ReadTogetherRepository import com.umc.ttoklip.module.onError +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 +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import javax.inject.Inject @@ -25,14 +31,29 @@ class ReadTogetherViewModelImpl @Inject constructor(private val repository: Read override val deadlineState: StateFlow get() = _deadlineState - private val _isOwner = MutableStateFlow(false) - override val isOwner: StateFlow - get() = _isOwner + private val _isWriter = MutableStateFlow(false) + override val isWriter: StateFlow + get() = _isWriter private val _postId: MutableStateFlow = MutableStateFlow(0L) override val postId: StateFlow get() = _postId + private val _writer = MutableStateFlow("") + override val writer: StateFlow + get() = _writer + + private val _toast = MutableSharedFlow() + override val toast: SharedFlow + get() = _toast + + private val _comments = MutableStateFlow(listOf()) + override val comments: StateFlow> + get() = _comments + + override val replyCommentParentId = MutableStateFlow(0) + override val commentContent = MutableStateFlow("") + private val _postContent: MutableStateFlow = MutableStateFlow( ViewTogetherResponse( @@ -68,16 +89,32 @@ class ReadTogetherViewModelImpl @Inject constructor(private val repository: Read } } + override fun setJoinState(joinState: Boolean) { + _joinState.value = joinState + } + override fun savePostId(postId: Long) { _postId.value = postId } + override fun checkWriter(writer: String) { + Log.d("local wrter", writer) + Log.d("writer", _writer.value) + _isWriter.value = writer.equals(_writer.value) + Log.d("isWrier", _isWriter.value.toString()) + } + + override fun readTogether(postId: Long) { viewModelScope.launch { repository.viewTogether(postId).onSuccess { _postContent.value = it _deadlineState.value = it.status != "IN_PROGRESS" + Log.d("_deadline", _deadlineState.value.toString()) _joinState.value = !it.alreadyJoin + _writer.value = it.writer + _comments.value = it.commentResponses + Log.d("response writer", _writer.value) }.onError { } @@ -87,27 +124,47 @@ class ReadTogetherViewModelImpl @Inject constructor(private val repository: Read override fun reportPost(reportRequest: ReportRequest) { viewModelScope.launch { if (postId.value != 0L) { - repository.reportTogether(postId.value, reportRequest) + repository.reportTogether(postId.value, reportRequest).onSuccess { + _toast.emit("게시글 신고가 완료되었습니다.") + }.onFail { + _toast.emit("게시글 신고 타입을 설정해주세요.") + } } } } - override fun reportComment(commentId: Long, reportRequest: ReportRequest) { + override fun reportComment( + commentId: Long, + reportRequest: ReportRequest + ) { viewModelScope.launch { - repository.reportTogetherComment(commentId, reportRequest) + repository.reportTogetherComment(commentId, reportRequest).onSuccess { + _toast.emit("댓글 신고가 완료되었습니다.") + }.onError { + Log.d("error", it.toString()) + }.onFail { + _toast.emit("댓글 신고 타입을 설정해주세요.") + } } } override fun deleteComment(commentId: Long) { viewModelScope.launch { - repository.deleteTogetherComment(commentId) + repository.deleteTogetherComment(commentId).onSuccess { + readTogether(postId.value) + } } } - override fun createComment(body: CreateCommentRequest) { + override fun createComment() { viewModelScope.launch { if (postId.value != 0L) { - repository.createTogetherComment(postId.value, body) + repository.createTogetherComment( + postId.value, + CreateCommentRequest(commentContent.value, replyCommentParentId.value.toLong()) + ).onSuccess { + readTogether(postId.value) + } } } } @@ -118,6 +175,7 @@ class ReadTogetherViewModelImpl @Inject constructor(private val repository: Read repository.joinTogether(postId.value).onSuccess { //_joinState.value = true readTogether(postId.value) + Log.d("join Together", it.toString()) } } } @@ -134,4 +192,25 @@ class ReadTogetherViewModelImpl @Inject constructor(private val repository: Read } } + override fun fetchParticipantsCount() { + viewModelScope.launch { + if (postId.value != 0L){ + repository.fetchParticipantsCount(postId.value).onSuccess { + Log.d("fetchParticipantsCount", it.toString()) + } + } + } + } + + override fun patchPostStatus(status: String) { + viewModelScope.launch{ + if (postId.value != 0L){ + repository.patchPostStatus(postId.value, PatchCartStatusRequest(status)).onSuccess { + _deadlineState.value = true + readTogether(postId.value) + Log.d("patchPostStatus", it.toString()) + } + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteTogetherActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/write/WriteTogetherActivity.kt similarity index 83% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteTogetherActivity.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/together/write/WriteTogetherActivity.kt index 3fd70ae8..a1cdb213 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteTogetherActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/write/WriteTogetherActivity.kt @@ -1,301 +1,298 @@ -package com.umc.ttoklip.presentation.hometown - -import android.content.Context -import android.content.Intent -import android.graphics.PorterDuff -import android.graphics.PorterDuffColorFilter -import android.graphics.Rect -import android.icu.text.DecimalFormat -import android.net.Uri -import android.text.Editable -import android.text.TextWatcher -import android.util.Log -import android.view.MotionEvent -import android.view.View -import android.view.inputmethod.EditorInfo -import android.view.inputmethod.InputMethodManager -import android.widget.EditText -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.PickVisualMediaRequest -import androidx.activity.result.contract.ActivityResultContracts -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.databinding.ActivityWriteTogetherBinding -import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.hometown.dialog.InputMaxMemberDialogFragment -import com.umc.ttoklip.presentation.hometown.dialog.TogetherDialog -import com.umc.ttoklip.presentation.honeytip.adapter.Image -import com.umc.ttoklip.presentation.honeytip.adapter.ImageRVA -import com.umc.ttoklip.presentation.honeytip.dialog.ImageDialogFragment -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch - -@AndroidEntryPoint -class WriteTogetherActivity : - BaseActivity(R.layout.activity_write_together) { - private val activityResultLauncher: ActivityResultLauncher = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { - val addressIntent = it.data - addressIntent?.let { aIntent -> - val address = aIntent.getStringExtra("address") - val addressDetail = aIntent.getStringExtra("addressDetail") - binding.tradingPlaceTv.setTextColor(getColor(R.color.black)) - binding.tradingPlaceTv.compoundDrawables.forEach { drawable -> - if (drawable != null) { - drawable.colorFilter = - PorterDuffColorFilter(getColor(R.color.black), PorterDuff.Mode.SRC_IN) - } - } - binding.tradingPlaceTv.text = if (!addressDetail.isNullOrBlank()) { - StringBuilder().append(address).append(" (").append(addressDetail).append(")") - .toString() - } else { - StringBuilder().append(address).toString() - } - } - } - private val imageAdapter by lazy { - ImageRVA(null) - } - - private val pickMultipleMedia = registerForActivityResult( - ActivityResultContracts.PickMultipleVisualMedia( - 100 - ) - ) { uris -> - if (uris.isNotEmpty()) { - updateImages(uris) - } else { - Log.d("PhotoPicker", "No media selected") - } - } - private val viewModel: WriteTogetherViewModel by viewModels() - override fun initView() { - binding.vm = viewModel as WriteTogetherViewModelImpl - initImageRVA() - addLink() - addImage() - binding.backBtn.setOnClickListener { - finish() - } - - binding.totalPriceTv.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = - Unit - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - s?.let { - if (it.isBlank()) { - viewModel.setTotalPrice(0) - viewModel.checkDone() - } - } - } - - override fun afterTextChanged(s: Editable?) = Unit - - }) - binding.totalPriceTv.setOnEditorActionListener { v, actionId, event -> - var current = binding.totalPriceTv.text.toString() - if (current.isBlank()) { - viewModel.setTotalPrice(0) - viewModel.checkDone() - } else { - if (current.contains(",")) { - current = current.replace(",", "") - } - viewModel.setTotalPrice(current.toLong()) - if (actionId == EditorInfo.IME_ACTION_NEXT) { - Log.d("price", current) - if (current.length > 3) { - val currentAmount = AMOUNT_FORMAT.format(current.toLong()) - binding.totalPriceTv.setText(currentAmount) -// binding.totalPriceTv.compoundDrawables.forEach { drawable -> -// if (drawable != null) { -// drawable.colorFilter = -// PorterDuffColorFilter( -// getColor(R.color.black), -// PorterDuff.Mode.SRC_IN -// ) -// } -// } - } - } - } - - false - } - - binding.maxMemberTv.setOnClickListener { - val bottomSheet = InputMaxMemberDialogFragment { member -> - viewModel.setTotalMember(member.toLong()) - binding.maxMemberTv.text = getString(R.string.max_member_format, member) - binding.maxMemberTv.compoundDrawables.forEach { drawable -> - if (drawable != null) { - drawable.colorFilter = - PorterDuffColorFilter( - getColor(R.color.black), - PorterDuff.Mode.SRC_IN - ) - } - } - binding.maxMemberTv.hint = "" - } - bottomSheet.show(supportFragmentManager, bottomSheet.tag) - } - - binding.tradingPlaceTv.setOnClickListener { - val intent = Intent(this, TradeLocationActivity::class.java) - activityResultLauncher.launch(intent) - } - } - - override fun initObserver() { - with(lifecycleScope) { - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.doneButtonActivated.collect { - binding.writeDoneBtn.isEnabled = it - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.title.collect { - viewModel.checkDone() - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.content.collect { - viewModel.checkDone() - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.totalPrice.collect { - viewModel.checkDone() - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.totalMember.collect { - viewModel.checkDone() - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.dealPlace.collect { - viewModel.checkDone() - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.openLink.collect { - viewModel.checkDone() - } - } - } - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.content.collect { - viewModel.checkDone() - } - } - } - - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.images.collect { - Log.d("uri image", it.toString()) - imageAdapter.submitList(it.toList()) - } - } - } - - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.doneWriteTogether.collect { - if (it) { - val together = TogetherDialog() - together.setDialogClickListener(object : - TogetherDialog.TogetherDialogClickListener { - override fun onClick() { - viewModel.writeTogether() - } - }) - together.show(supportFragmentManager, together.tag) - } - } - } - } - - launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.closePage.collect { - if (it) finish() - } - } - } - } - } - - private fun addLink() { - binding.addLinkBtn.setOnClickListener { - binding.addLinkBtn.visibility = View.GONE - binding.inputUrlBtn.visibility = View.VISIBLE - } - } - - private fun initImageRVA() { - binding.imageRv.adapter = imageAdapter - } - - private fun addImage() { - binding.addImageBtn.setOnClickListener { - val imageDialog = ImageDialogFragment() - imageDialog.setDialogClickListener(object : ImageDialogFragment.DialogClickListener { - override fun onClick() { - binding.imageRv.visibility = View.VISIBLE - pickMultipleMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)) - } - }) - imageDialog.show(supportFragmentManager, imageDialog.tag) - } - } - - private fun updateImages(uriList: List) { - Log.d("uri", uriList.toString()) - val images = uriList.map { Image(it) } - viewModel.addImages(images) - } - - override fun dispatchTouchEvent(event: MotionEvent?): Boolean { - if (event?.action == MotionEvent.ACTION_DOWN) { - val v = currentFocus - if (v is EditText) { - val outRect = Rect() - v.getGlobalVisibleRect(outRect) - if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) { - v.clearFocus() - val imm: InputMethodManager = - getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(v.getWindowToken(), 0) - } - } - } - return super.dispatchTouchEvent(event) - } - - companion object { - private val AMOUNT_FORMAT = DecimalFormat("#,###") - } +package com.umc.ttoklip.presentation.hometown.together.write + +import android.content.Context +import android.content.Intent +import android.graphics.PorterDuff +import android.graphics.PorterDuffColorFilter +import android.graphics.Rect +import android.icu.text.DecimalFormat +import android.net.Uri +import android.text.Editable +import android.text.TextUtils +import android.text.TextWatcher +import android.util.Log +import android.view.MotionEvent +import android.view.View +import android.view.inputmethod.EditorInfo +import android.view.inputmethod.InputMethodManager +import android.widget.EditText +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.PickVisualMediaRequest +import androidx.activity.result.contract.ActivityResultContracts +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.databinding.ActivityWriteTogetherBinding +import com.umc.ttoklip.presentation.base.BaseActivity +import com.umc.ttoklip.presentation.hometown.TradeLocationActivity +import com.umc.ttoklip.presentation.hometown.dialog.InputMaxMemberDialogFragment +import com.umc.ttoklip.presentation.hometown.dialog.TogetherDialog +import com.umc.ttoklip.presentation.honeytip.adapter.Image +import com.umc.ttoklip.presentation.honeytip.adapter.ImageRVA +import com.umc.ttoklip.presentation.dialog.ImageDialogFragment +import com.umc.ttoklip.presentation.hometown.together.read.ReadTogetherActivity +import com.umc.ttoklip.presentation.honeytip.read.ReadHoneyTipActivity +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class WriteTogetherActivity : + BaseActivity(R.layout.activity_write_together) { + private val activityResultLauncher: ActivityResultLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + val addressIntent = it.data + addressIntent?.let { aIntent -> + val address = aIntent.getStringExtra("address") + val addressDetail = aIntent.getStringExtra("addressDetail") + binding.tradingPlaceTv.setTextColor(getColor(R.color.black)) + binding.tradingPlaceTv.compoundDrawables.forEach { drawable -> + if (drawable != null) { + drawable.colorFilter = + PorterDuffColorFilter(getColor(R.color.black), PorterDuff.Mode.SRC_IN) + } + } + binding.tradingPlaceTv.text = if (!addressDetail.isNullOrBlank()) { + StringBuilder().append(address).append(" (").append(addressDetail).append(")") + .toString() + } else { + StringBuilder().append(address).toString() + } + } + } + private val imageAdapter by lazy { + ImageRVA(this, null) + } + + private val pickMultipleMedia = registerForActivityResult( + ActivityResultContracts.PickMultipleVisualMedia( + 100 + ) + ) { uris -> + if (uris.isNotEmpty()) { + updateImages(uris) + } else { + Log.d("PhotoPicker", "No media selected") + } + } + private val viewModel: WriteTogetherViewModel by viewModels() + override fun initView() { + binding.vm = viewModel as WriteTogetherViewModelImpl + initImageRVA() + addLink() + addImage() + binding.backBtn.setOnClickListener { + finish() + } + + var result = "" + + binding.totalPriceTv.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = + Unit + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + if(!TextUtils.isEmpty(s.toString()) && s.toString() != result){ + result = s.toString().replace(",","") + viewModel.setTotalPrice(result.toLong()) + result = AMOUNT_FORMAT.format(result.toDouble()) + binding.totalPriceTv.setText(result) + binding.totalPriceTv.setSelection(result.length) + } + s?.let { + if (it.isBlank()) { + viewModel.setTotalPrice(0) + viewModel.checkDone() + result = "" + } + } + } + + override fun afterTextChanged(s: Editable?) = Unit + + }) + + binding.maxMemberTv.setOnClickListener { + val bottomSheet = InputMaxMemberDialogFragment { member -> + viewModel.setTotalMember(member.toLong()) + binding.maxMemberTv.text = getString(R.string.max_member_format, member) + binding.maxMemberTv.compoundDrawables.forEach { drawable -> + if (drawable != null) { + drawable.colorFilter = + PorterDuffColorFilter( + getColor(R.color.black), + PorterDuff.Mode.SRC_IN + ) + } + } + binding.maxMemberTv.hint = "" + } + bottomSheet.show(supportFragmentManager, bottomSheet.tag) + } + + binding.tradingPlaceTv.setOnClickListener { + val intent = Intent(this, TradeLocationActivity::class.java) + activityResultLauncher.launch(intent) + } + } + + override fun initObserver() { + with(lifecycleScope) { + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.doneButtonActivated.collect { + Log.d("enable", it.toString()) + binding.writeDoneBtn.isEnabled = it + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.title.collect { + Log.d("text", it) + viewModel.checkDone() + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.content.collect { + Log.d("content", it) + viewModel.checkDone() + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.totalPrice.collect { + Log.d("price", it.toString()) + viewModel.checkDone() + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.totalMember.collect { + Log.d("member", it.toString()) + viewModel.checkDone() + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.dealPlace.collect { + viewModel.checkDone() + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.openLink.collect { + viewModel.checkDone() + } + } + } + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.content.collect { + viewModel.checkDone() + } + } + } + + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.images.collect { + Log.d("uri image", it.toString()) + imageAdapter.submitList(it.toList()) + } + } + } + + launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.doneWriteTogether.collect { + if (it) { + val together = TogetherDialog() + together.setDialogClickListener(object : + TogetherDialog.TogetherDialogClickListener { + override fun onClick() { + viewModel.writeTogether() + } + }) + together.show(supportFragmentManager, together.tag) + } + } + } + } + + launch { + repeatOnLifecycle(Lifecycle.State.STARTED){ + viewModel.postId.collect{ + if(it != 0L) { + startActivity( + ReadTogetherActivity.newIntent( + this@WriteTogetherActivity, + it + ) + ) + finish() + } + } + } + } + } + } + + private fun addLink() { + binding.addLinkBtn.setOnClickListener { + binding.addLinkBtn.visibility = View.GONE + binding.inputUrlBtn.visibility = View.VISIBLE + } + } + + private fun initImageRVA() { + binding.imageRv.adapter = imageAdapter + } + + private fun addImage() { + binding.addImageBtn.setOnClickListener { + val imageDialog = ImageDialogFragment() + imageDialog.setDialogClickListener(object : ImageDialogFragment.DialogClickListener { + override fun onClick() { + binding.imageRv.visibility = View.VISIBLE + pickMultipleMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)) + } + }) + imageDialog.show(supportFragmentManager, imageDialog.tag) + } + } + + private fun updateImages(uriList: List) { + Log.d("uri", uriList.toString()) + val images = uriList.map { Image(it, "") } + viewModel.addImages(images) + } + + override fun dispatchTouchEvent(event: MotionEvent?): Boolean { + if (event?.action == MotionEvent.ACTION_DOWN) { + val v = currentFocus + if (v is EditText) { + val outRect = Rect() + v.getGlobalVisibleRect(outRect) + if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) { + v.clearFocus() + val imm: InputMethodManager = + getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(v.getWindowToken(), 0) + } + } + } + return super.dispatchTouchEvent(event) + } + + companion object { + private val AMOUNT_FORMAT = DecimalFormat("#,###") + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteTogetherViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/write/WriteTogetherViewModel.kt similarity index 84% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteTogetherViewModel.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/together/write/WriteTogetherViewModel.kt index a46a917a..321a98bb 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteTogetherViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/write/WriteTogetherViewModel.kt @@ -1,6 +1,7 @@ -package com.umc.ttoklip.presentation.hometown +package com.umc.ttoklip.presentation.hometown.together.write import com.umc.ttoklip.presentation.honeytip.adapter.Image +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow interface WriteTogetherViewModel { @@ -15,6 +16,7 @@ interface WriteTogetherViewModel { val doneWriteTogether: StateFlow val closePage: StateFlow val images: StateFlow> + val postId: StateFlow fun setTotalPrice(totalPrice: Long) fun setTotalMember(totalMember: Long) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteTogetherViewModelImpl.kt b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/write/WriteTogetherViewModelImpl.kt similarity index 91% rename from app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteTogetherViewModelImpl.kt rename to app/src/main/java/com/umc/ttoklip/presentation/hometown/together/write/WriteTogetherViewModelImpl.kt index 9bcf19bb..6c1d7d79 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/hometown/WriteTogetherViewModelImpl.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/hometown/together/write/WriteTogetherViewModelImpl.kt @@ -1,4 +1,4 @@ -package com.umc.ttoklip.presentation.hometown +package com.umc.ttoklip.presentation.hometown.together.write import android.content.Context import android.util.Log @@ -67,9 +67,14 @@ class WriteTogetherViewModelImpl @Inject constructor( override val images: StateFlow> get() = _images + private val _postId = MutableStateFlow(0L) + override val postId: StateFlow + get() = _postId + override fun setTotalPrice(totalPrice: Long) { _totalPrice.value = totalPrice + Log.d("set price", _totalPrice.value.toString()) } override fun setTotalMember(totalMember: Long) { @@ -86,6 +91,7 @@ class WriteTogetherViewModelImpl @Inject constructor( override fun checkDone() { _doneButtonActivated.value = title.value.isNotBlank() && openLink.value.isNotBlank() && content.value.isNotBlank() && totalPrice.value > 0 && totalMember.value > 0 + Log.d("checkDone", _doneButtonActivated.value.toString()) } override fun doneButtonClick() { @@ -107,6 +113,7 @@ class WriteTogetherViewModelImpl @Inject constructor( Log.d("request", request.toString()) viewModelScope.launch { repository.createTogether(request).onSuccess { + _postId.value = it.message.replace(("[^\\d]").toRegex(), "").toLong() _closePage.value = true }.onError { Log.d("writetogethererror", it.toString()) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipConst.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipConst.kt index 6b5fd229..6633f75a 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipConst.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipConst.kt @@ -1,5 +1,5 @@ package com.umc.ttoklip.presentation.honeytip const val BOARD = "board" -const val HONEY_TIP = "꿀팁 공유" +const val HONEY_TIPS = "꿀팁 공유" const val ASK = "질문해요" \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipFragment.kt index fea2240c..8e0a1af6 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipFragment.kt @@ -25,7 +25,7 @@ class HoneyTipFragment: BaseFragment(R.layout.frag DailyPopularHoneyTipsVPA{ val intent = Intent(requireContext(), ReadHoneyTipActivity::class.java) intent.putExtra("postId", it.id) - intent.putExtra(BOARD, HONEY_TIP) + intent.putExtra(BOARD, HONEY_TIPS) startActivity(intent) } } @@ -117,7 +117,7 @@ class HoneyTipFragment: BaseFragment(R.layout.frag private fun initCategoryViewPager() { val tabTitles = listOf("집안일", "레시피", "안전한생활", "복지\u00b7정책") - binding.categoryVp.adapter = CategoryVPA(this, HONEY_TIP, tabTitles.size) + binding.categoryVp.adapter = CategoryVPA(this, HONEY_TIPS, tabTitles.size) TabLayoutMediator(binding.categoryTablayout, binding.categoryVp) { tab, position -> tab.text = tabTitles[position] }.attach() diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipMainFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipMainFragment.kt index 802a7625..c5869c0b 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipMainFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/HoneyTipMainFragment.kt @@ -22,7 +22,7 @@ import kotlinx.coroutines.launch @AndroidEntryPoint class HoneyTipMainFragment : BaseFragment(R.layout.fragment_honey_tip) { - private var board = HONEY_TIP + private var board = HONEY_TIPS private val viewModel: HoneyTipViewModel by viewModels() override fun initObserver() { lifecycleScope.launch { @@ -66,7 +66,7 @@ class HoneyTipMainFragment : BaseFragment(R.layout.frag } private fun initTabLayout() { - val tabTitles = listOf(HONEY_TIP, ASK) + val tabTitles = listOf(HONEY_TIPS, ASK) binding.boardVp.adapter = HoneyTipAndQuestionVPA(this) binding.boardVp.isUserInputEnabled = false Log.d("position", binding.boardTablayout.selectedTabPosition.toString()) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/QuestionFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/QuestionFragment.kt index c5f00df2..9f70e770 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/QuestionFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/QuestionFragment.kt @@ -25,7 +25,7 @@ class QuestionFragment: BaseFragment(R.layout.frag DailyPopularHoneyTipsVPA{ val intent = Intent(requireContext(), ReadHoneyTipActivity::class.java) intent.putExtra("postId", it.id) - intent.putExtra(BOARD, HONEY_TIP) + intent.putExtra(BOARD, HONEY_TIPS) startActivity(intent) } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/ShareHoneyTipFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/ShareHoneyTipFragment.kt index e7570de2..b70c3402 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/ShareHoneyTipFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/ShareHoneyTipFragment.kt @@ -1,7 +1,6 @@ package com.umc.ttoklip.presentation.honeytip import android.content.Intent -import android.util.Log import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -26,7 +25,7 @@ class ShareHoneyTipFragment( DailyPopularHoneyTipsVPA{ val intent = Intent(requireContext(), ReadHoneyTipActivity::class.java) intent.putExtra("honeyTipId", it.id) - intent.putExtra(BOARD, HONEY_TIP) + intent.putExtra(BOARD, HONEY_TIPS) startActivity(intent) } } @@ -89,7 +88,7 @@ class ShareHoneyTipFragment( private fun initCategoryViewPager() { val tabTitles = listOf("집안일", "레시피", "안전한 생활", "복지 \u00b7 정책") - binding.categoryVp.adapter = CategoryVPA(this, HONEY_TIP, tabTitles.size) + binding.categoryVp.adapter = CategoryVPA(this, HONEY_TIPS, tabTitles.size) TabLayoutMediator(binding.categoryTablayout, binding.categoryVp) { tab, position -> tab.text = tabTitles[position] }.attach() diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/CategoryVPA.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/CategoryVPA.kt index 629082c6..2de4d5f4 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/CategoryVPA.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/CategoryVPA.kt @@ -2,7 +2,7 @@ package com.umc.ttoklip.presentation.honeytip.adapter import androidx.fragment.app.Fragment import androidx.viewpager2.adapter.FragmentStateAdapter -import com.umc.ttoklip.presentation.honeytip.HONEY_TIP +import com.umc.ttoklip.presentation.honeytip.HONEY_TIPS import com.umc.ttoklip.presentation.honeytip.honeytiplist.HouseWorkHoneyTipListFragment import com.umc.ttoklip.presentation.honeytip.honeytiplist.RecipeHoneyTipListFragment import com.umc.ttoklip.presentation.honeytip.honeytiplist.SafeLivingHoneyTipListFragment @@ -36,6 +36,6 @@ class CategoryVPA( } override fun createFragment(position: Int): Fragment { - return if(caller == HONEY_TIP) honeyTipFragmentList[position] else questionFragmentList[position] + return if(caller == HONEY_TIPS) honeyTipFragmentList[position] else questionFragmentList[position] } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/HoneyTipAndQuestionVPA.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/HoneyTipAndQuestionVPA.kt index 827b8886..88040fcb 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/HoneyTipAndQuestionVPA.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/HoneyTipAndQuestionVPA.kt @@ -2,12 +2,8 @@ package com.umc.ttoklip.presentation.honeytip.adapter import androidx.fragment.app.Fragment import androidx.viewpager2.adapter.FragmentStateAdapter -import com.umc.ttoklip.data.model.honeytip.HoneyTipMainResponse -import com.umc.ttoklip.presentation.honeytip.ASK -import com.umc.ttoklip.presentation.honeytip.HONEY_TIP import com.umc.ttoklip.presentation.honeytip.HoneyTipFragment import com.umc.ttoklip.presentation.honeytip.QuestionFragment -import com.umc.ttoklip.presentation.honeytip.ShareHoneyTipFragment class HoneyTipAndQuestionVPA( fragment: Fragment, diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/ImageRVA.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/ImageRVA.kt index 89ee343d..e06518d3 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/ImageRVA.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/adapter/ImageRVA.kt @@ -12,7 +12,7 @@ import com.bumptech.glide.Glide import com.umc.ttoklip.databinding.ItemImageBinding import okhttp3.internal.assertThreadDoesntHoldLock -class ImageRVA(private var listener: OnImageClickListener?): ListAdapter(object : DiffUtil.ItemCallback(){ +class ImageRVA(private val context: Context, private var listener: OnImageClickListener?): ListAdapter(object : DiffUtil.ItemCallback(){ override fun areItemsTheSame(oldItem: Image, newItem: Image): Boolean { return oldItem === newItem } @@ -24,8 +24,14 @@ class ImageRVA(private var listener: OnImageClickListener?): ListAdapter viewModel.replyCommentParentId.value = id }, { id, myComment -> + Log.d("mycomment", myComment.toString()) if (myComment) { val deleteDialog = DeleteDialogFragment() deleteDialog.setDialogClickListener(object : @@ -70,6 +71,8 @@ class ReadHoneyTipActivity : }) reportDialog.show(supportFragmentManager, reportDialog.tag) } + }, { nick -> + startActivity(OtherUserActivity.newIntent(this, nick)) }) } @@ -154,7 +157,6 @@ class ReadHoneyTipActivity : showReportBtn() } } - else -> {} } } @@ -192,14 +194,10 @@ class ReadHoneyTipActivity : binding.backBtn.setOnClickListener { finish() } - - initImageRVA() showDeleteDialog() showReportDialog() editHoneyTip() - - } private fun initImageRVA() { @@ -236,7 +234,7 @@ class ReadHoneyTipActivity : binding.editBtn.setOnClickListener { val intent = Intent(this, WriteHoneyTipActivity::class.java) intent.putExtra("isEdit", true) - intent.putExtra(BOARD, HONEY_TIP) + intent.putExtra(BOARD, com.umc.ttoklip.presentation.honeytip.HONEY_TIPS) val images = imageAdapter.currentList.filterIsInstance()?.map { it.imageUrl } ?.toTypedArray() val editHoneyTip = EditHoneyTip( @@ -247,6 +245,7 @@ class ReadHoneyTipActivity : images ?: emptyArray(), binding.linkT.text.toString() ) + Log.d("honeyTip", editHoneyTip.toString()) intent.putExtra("honeyTip", editHoneyTip) startActivity(intent) finish() @@ -317,10 +316,9 @@ class ReadHoneyTipActivity : } companion object { - const val HONEY_TIP = "postId" fun newIntent(context: Context, id: Int) = Intent(context, ReadHoneyTipActivity::class.java).apply { - putExtra(HONEY_TIP, id) + putExtra("postId", id) } } } \ No newline at end of file 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 fae4a9cf..0cb2778b 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 @@ -15,21 +15,16 @@ import com.umc.ttoklip.TtoklipApplication import com.umc.ttoklip.data.model.honeytip.ImageUrl import com.umc.ttoklip.data.model.honeytip.request.ReportRequest import com.umc.ttoklip.data.model.news.comment.NewsCommentResponse -import com.umc.ttoklip.databinding.ActivityReadHoneyTipBinding import com.umc.ttoklip.databinding.ActivityReadQuestionBinding import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.honeytip.BOARD -import com.umc.ttoklip.presentation.honeytip.HONEY_TIP import com.umc.ttoklip.presentation.honeytip.ImageViewActivity import com.umc.ttoklip.presentation.honeytip.adapter.OnReadImageClickListener import com.umc.ttoklip.presentation.honeytip.adapter.QuestionCommentRVA 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.CommentRVA +import com.umc.ttoklip.presentation.dialog.DeleteDialogFragment +import com.umc.ttoklip.presentation.dialog.ReportDialogFragment import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch -import org.w3c.dom.Comment @AndroidEntryPoint class ReadQuestionActivity : BaseActivity(R.layout.activity_read_question), diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/write/WriteHoneyTipActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/write/WriteHoneyTipActivity.kt index a3229a96..f126adf0 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/write/WriteHoneyTipActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/write/WriteHoneyTipActivity.kt @@ -35,17 +35,21 @@ import com.umc.ttoklip.data.model.honeytip.EditHoneyTip import com.umc.ttoklip.databinding.ActivityWriteHoneyTipBinding import com.umc.ttoklip.presentation.base.BaseActivity import com.umc.ttoklip.presentation.honeytip.BOARD -import com.umc.ttoklip.presentation.honeytip.HONEY_TIP +import com.umc.ttoklip.presentation.honeytip.HONEY_TIPS import com.umc.ttoklip.presentation.honeytip.ImageViewActivity import com.umc.ttoklip.presentation.honeytip.adapter.Image import com.umc.ttoklip.presentation.honeytip.adapter.ImageRVA import com.umc.ttoklip.presentation.honeytip.adapter.OnImageClickListener -import com.umc.ttoklip.presentation.honeytip.dialog.ImageDialogFragment +import com.umc.ttoklip.presentation.dialog.ImageDialogFragment import com.umc.ttoklip.presentation.honeytip.read.ReadHoneyTipActivity import com.umc.ttoklip.presentation.honeytip.read.ReadQuestionActivity import com.umc.ttoklip.util.WriteHoneyTipUtil +import com.umc.ttoklip.util.uriToFile import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import java.io.ByteArrayOutputStream import java.io.File @@ -55,9 +59,10 @@ class WriteHoneyTipActivity : BaseActivity(R.layout.activity_write_honey_tip), OnImageClickListener { private val imageAdapter: ImageRVA by lazy { - ImageRVA(this) + ImageRVA(this, this) } private val board: String by lazy { + Log.d("board", intent.getStringExtra(BOARD)!!) intent.getStringExtra(BOARD)!! } private val viewModel: WriteHoneyTipViewModel by viewModels() @@ -65,6 +70,7 @@ class WriteHoneyTipActivity : private var isEdit = false private var postId = 0 private var editImage = mutableListOf() + private var selectedImageUris: List? = null private val pickMultipleMedia = registerForActivityResult( ActivityResultContracts.PickMultipleVisualMedia( @@ -72,7 +78,8 @@ class WriteHoneyTipActivity : ) ) { uris -> if (uris.isNotEmpty()) { - updateImages(uris) + selectedImageUris = uris + updateImages() } else { Log.d("PhotoPicker", "No media selected") } @@ -101,17 +108,6 @@ class WriteHoneyTipActivity : } } } - - viewModel.isBodyNull.observe(this) { - Log.d("body", it.toString()) - if(!isEdit) - binding.writeDoneBtn.isEnabled = viewModel.isBodyNull.value == false && viewModel.isTitleNull.value == false - } - viewModel.isTitleNull.observe(this) { - Log.d("title", it.toString()) - if(!isEdit) - binding.writeDoneBtn.isEnabled = viewModel.isBodyNull.value == false && viewModel.isTitleNull.value == false - } } private fun handleEvent(event: WriteHoneyTipViewModel.WriteDoneEvent) { @@ -138,14 +134,14 @@ class WriteHoneyTipActivity : if (!isEdit){ return } else { + viewModel.isEdit.value = true + viewModel.isWriteDoneBtnEnable.value = true val editHoneyTip = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { intent.getSerializableExtra("honeyTip", EditHoneyTip::class.java) } else { intent.getSerializableExtra("honeyTip") as EditHoneyTip } with(binding) { - writeDoneBtn.isEnabled = true - writeDoneBtn.text = "수정완료" titleEt.setText(editHoneyTip?.title) bodyEt.setText(editHoneyTip?.content) inputUrlEt.setText(editHoneyTip?.url) @@ -156,6 +152,7 @@ class WriteHoneyTipActivity : val images = editHoneyTip?.image?.toList() Log.d("edit images", images.toString()) convertURLtoURI(images) + imageAdapter.submitList(images?.map { Image(Uri.EMPTY ,it) }) postId = editHoneyTip?.postId ?: 0 category = editHoneyTip?.category?:"" binding.tabLayout.selectTab(binding.tabLayout.getTabAt(stringToNum(category))) @@ -165,7 +162,6 @@ class WriteHoneyTipActivity : private fun convertURLtoURI(photos: List?) { val uris = mutableListOf() photos?.forEach { - Log.d("uris", uris.toString()) Glide.with(this).asBitmap().load(it) .into(object : CustomTarget() { override fun onResourceReady( @@ -175,7 +171,8 @@ class WriteHoneyTipActivity : Log.d("bittmap", resource.toString()) uris.add(getImageUri(this@WriteHoneyTipActivity, resource)) if (uris.size == photos.size) { - imageAdapter.submitList(uris.map { it -> Image(it) }) + Log.d("uris", uris.toString()) + //imageAdapter.submitList(uris.map { it -> Image(it, "") }) editImage.addAll(uris) } } @@ -215,7 +212,8 @@ class WriteHoneyTipActivity : } private fun checkHoneyTipOrQuestion() { - if (board == HONEY_TIP) { + Log.d("title", board.toString()) + if (board == HONEY_TIPS) { binding.titleTv.text = "꿀팁 공유하기" //editHoneyTip() @@ -229,19 +227,9 @@ class WriteHoneyTipActivity : private fun enableWriteDoneButton() { binding.titleEt.addTextChangedListener(object : TextWatcher{ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - if(s.toString().isNotBlank()){ - viewModel.setTitle(false) - } else { - viewModel.setTitle(true) - } } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - if(s.toString().isNotBlank()){ - viewModel.setTitle(false) - } else { - viewModel.setTitle(true) - } } override fun afterTextChanged(s: Editable?) { @@ -256,26 +244,16 @@ class WriteHoneyTipActivity : binding.bodyEt.addTextChangedListener(object : TextWatcher{ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - if(s.toString().isNotBlank()){ - viewModel.setBody(false) - } else { - viewModel.setBody(true) - } } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - if(s.toString().isNotBlank()){ - viewModel.setBody(false) - } else { - viewModel.setBody(true) - } } override fun afterTextChanged(s: Editable?) { if(s.toString().isNotBlank()){ - viewModel.setBody(false) + viewModel.setContent(false) } else { - viewModel.setBody(true) + viewModel.setContent(true) } } @@ -284,53 +262,57 @@ class WriteHoneyTipActivity : private fun writeDone() { binding.writeDoneBtn.setOnClickListener { - val images = - imageAdapter.currentList.filterIsInstance().map { it.uri }.toList() - val imageParts = WriteHoneyTipUtil(this).convertUriListToMultiBody(images) + /*val beforeEditImages = + imageAdapter.currentList.filterIsInstance().map { it.url }.toList() + //convertURLtoURI(beforeEditImages) + val images = editImage + imageAdapter.currentList.filterIsInstance().map { it.uri }.filter { it != Uri.EMPTY }.toList() + Log.d("write done", images.size.toString()) + val imageParts = WriteHoneyTipUtil(this).convertUriListToMultiBody(images)*/ + Log.d("selectedImageUris", selectedImageUris.toString()) + val imageParts = mutableListOf() + val images = imageAdapter.currentList.filterIsInstance().map { it.uri }.filter { it != Uri.EMPTY }.toList() + if(selectedImageUris == null || selectedImageUris!!.isEmpty()){ + imageParts.add(null) + } + images.forEachIndexed { index, uri -> + val file = uriToFile(uri) + val requestFile = file.asRequestBody("image/*".toMediaTypeOrNull()) + val body = MultipartBody.Part.createFormData("images", file.name, requestFile) + imageParts.add(body) + } imageParts.forEach { - Log.d("용량", "${it.body.contentLength().toDouble() / (1024 * 1024)}") - if(it.body.contentLength().toDouble() / (1024 * 1024) > 10){ - Toast.makeText(this, "사진 용량은 10MB로 제한되어있습니다.", Toast.LENGTH_SHORT).show() - return@setOnClickListener + if(it != null) { + Log.d("용량", "${it.body.contentLength().toDouble() / (1024 * 1024)}") + if (it.body.contentLength().toDouble() / (1024 * 1024) > 10) { + Toast.makeText(this, "사진 용량은 10MB로 제한되어있습니다.", Toast.LENGTH_SHORT).show() + return@setOnClickListener + } } } val title = binding.titleEt.text.toString() val content = binding.bodyEt.text.toString() - val category = category.toString() - Log.d("write done category", category) + val category = category val url = binding.inputUrlEt.text.toString() if(isEdit){ Log.d("it Edit", isEdit.toString()) viewModel.editHoneyTip(postId, title, content, category, imageParts, url) + Log.d("edit image imagepart", imageParts.toString()) editImage.forEach{ val delete = deleteImage(this@WriteHoneyTipActivity, it) Log.d("delete", delete.toString()) } } else { - if (board == HONEY_TIP) { + if (board == HONEY_TIPS) { viewModel.createHoneyTip(title, content, category, imageParts, url) } else { - viewModel.createQuestion(title, content, category, imageParts) + //viewModel.createQuestion(title, content, category, imageParts) } } } } - fun getFileSize(filePath: String): Long { - val file = File(filePath) - - // 파일이 존재하는지 확인 - if (file.exists()) { - // 파일 크기를 바이트 단위로 반환 - return file.length() - } else { - // 파일이 존재하지 않으면 -1 또는 다른 값으로 처리 - return -1 - } - } - private fun initImageRVA() { //imageAdapter = ImageRVA(this) binding.imageRv.adapter = imageAdapter @@ -418,14 +400,17 @@ class WriteHoneyTipActivity : } } - private fun updateImages(uriList: List) { + private fun updateImages() { + if(selectedImageUris.isNullOrEmpty()){ + return + } // uri 권한 확장 val flag = Intent.FLAG_GRANT_READ_URI_PERMISSION - uriList.forEach { + selectedImageUris!!.forEach { applicationContext.contentResolver.takePersistableUriPermission(it, flag) } - val images = uriList.map { Image(it) } + val images = selectedImageUris!!.map { Image(it, "") } val updatedImages = imageAdapter.currentList.toMutableList().apply { addAll(images) } imageAdapter.submitList(updatedImages) } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/write/WriteHoneyTipViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/write/WriteHoneyTipViewModel.kt index d0ab688b..26e92078 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/honeytip/write/WriteHoneyTipViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/honeytip/write/WriteHoneyTipViewModel.kt @@ -11,7 +11,9 @@ import com.umc.ttoklip.module.onSuccess import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaTypeOrNull @@ -33,18 +35,27 @@ class WriteHoneyTipViewModel @Inject constructor( data class WriteDoneQuestion(val postId: Int) : WriteDoneEvent() } - val isTitleNull: LiveData by lazy { _isTitleNull } - private val _isTitleNull by lazy { MutableLiveData(true) } + private val _isTitleNull = MutableStateFlow(true) + private val _isContentNull = MutableStateFlow(true) - val isBodyNull: LiveData by lazy { _isBodyNull } - private val _isBodyNull by lazy { MutableLiveData(true) } + private val _content = MutableStateFlow("") + val content = _content.asStateFlow() + + private val _title = MutableStateFlow("") + val title = _title.asStateFlow() + + val isEdit = MutableStateFlow(false) + + val isWriteDoneBtnEnable = MutableStateFlow(false) fun setTitle(boolean: Boolean) { _isTitleNull.value = boolean + isWriteDoneBtnEnable.value = (_isTitleNull.value.not() && _isContentNull.value.not()) or isEdit.value } - fun setBody(boolean: Boolean) { - _isBodyNull.value = boolean + fun setContent(boolean: Boolean) { + _isContentNull.value = boolean + isWriteDoneBtnEnable.value = (_isTitleNull.value.not() && _isContentNull.value.not()) or isEdit.value } private fun convertStringToTextPlain(string: String): RequestBody { @@ -61,7 +72,7 @@ class WriteHoneyTipViewModel @Inject constructor( title: String, content: String, category: String, - images: Array, + images: List, url: String ) { viewModelScope.launch(Dispatchers.IO) { @@ -84,7 +95,7 @@ class WriteHoneyTipViewModel @Inject constructor( title: String, content: String, category: String, - images: Array, + images: List, url: String ) { viewModelScope.launch(Dispatchers.IO) { @@ -109,7 +120,7 @@ class WriteHoneyTipViewModel @Inject constructor( title: String, content: String, category: String, - images: Array + images: List ) { viewModelScope.launch(Dispatchers.IO) { repository.createQuestion( diff --git a/app/src/main/java/com/umc/ttoklip/presentation/intro/SplashActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/intro/SplashActivity.kt index d5c5ff09..5d118646 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/intro/SplashActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/intro/SplashActivity.kt @@ -16,13 +16,13 @@ class SplashActivity:BaseActivity(R.layout.activity_splas handler.postDelayed({ val spf=getSharedPreferences("first", MODE_PRIVATE) val firstRun=spf.getBoolean("firstRun",true) - TtoklipApplication.prefs.setBoolean("isFirstLogin", false) + TtoklipApplication.prefs.setBoolean("isFirstLogin", true) val jwt=TtoklipApplication.prefs.getString("jwt","") val isFirstLogin=TtoklipApplication.prefs.getBoolean("isFirstLogin",true) if(firstRun){ startActivity(Intent(this, IntroActivity::class.java)) finish() - }else if(jwt.isNotEmpty()&&!isFirstLogin){ + }else if(jwt.isNotEmpty()&&!isFirstLogin){ //로그인 토큰 확인 필요시 해당 부분 주석 startActivity(Intent(this,MainActivity::class.java)) finish() } else{ diff --git a/app/src/main/java/com/umc/ttoklip/presentation/login/LoginActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/login/LoginActivity.kt index ef43b61d..436f6e0a 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/login/LoginActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/login/LoginActivity.kt @@ -10,6 +10,7 @@ import androidx.lifecycle.repeatOnLifecycle import com.kakao.sdk.auth.model.OAuthToken import com.kakao.sdk.common.model.ClientError import com.kakao.sdk.common.model.ClientErrorCause +import com.kakao.sdk.common.util.Utility import com.kakao.sdk.user.UserApiClient import com.navercorp.nid.NaverIdLoginSDK import com.navercorp.nid.oauth.OAuthLoginCallback @@ -30,73 +31,78 @@ class LoginActivity : BaseActivity(R.layout.activity_login private val viewModel: LoginViewModel by viewModels() - override fun initView() { + override fun initView() {6 loginActivity=this - binding.loginNaverBtn.setOnClickListener { - val oauthLoginCallback = object : OAuthLoginCallback { - override fun onError(errorCode: Int, message: String) { - onFailure(errorCode, message) - } + naverLogin() + } + binding.loginKakaoBtn.setOnClickListener { + kakaoLogin() + } + } - override fun onFailure(httpStatus: Int, message: String) { - val errorCode = NaverIdLoginSDK.getLastErrorCode().code - val errorDescription = NaverIdLoginSDK.getLastErrorDescription() - Log.e("NAVER-LOGIN", "errorCode:$errorCode, errorDesc:$errorDescription") - } + companion object{ + var loginActivity:LoginActivity?=null + } - override fun onSuccess() { - Log.i("NAVER-LOGIN", "로그인 성공") - val loginRequest = LoginRequest("${NaverIdLoginSDK.getAccessToken()}", "naver") - viewModel.postLogin(loginRequest) - } + private fun naverLogin(){ + val oauthLoginCallback = object : OAuthLoginCallback { + override fun onError(errorCode: Int, message: String) { + onFailure(errorCode, message) + } + + override fun onFailure(httpStatus: Int, message: String) { + val errorCode = NaverIdLoginSDK.getLastErrorCode().code + val errorDescription = NaverIdLoginSDK.getLastErrorDescription() + Log.e("NAVER-LOGIN", "errorCode:$errorCode, errorDesc:$errorDescription") + } + + override fun onSuccess() { + Log.i("NAVER-LOGIN", "로그인 성공") + val loginRequest = LoginRequest("${NaverIdLoginSDK.getAccessToken()}", "naver") + viewModel.postLogin(loginRequest) + } + } + NaverIdLoginSDK.authenticate(this, oauthLoginCallback) + //네이버 토큰 임시확인용 + Log.i("NAVER-LOGIN","${NaverIdLoginSDK.getAccessToken()}") + } + private fun kakaoLogin(){ + val callback: (OAuthToken?, Throwable?) -> Unit = { token, error -> + if (error != null) { + Log.e("카카오로그인", "카카오계정으로 로그인 실패", error) + } else if (token != null) { + Log.i("카카오로그인", "카카오계정으로 로그인 성공") + val loginRequest = LoginRequest("${token.accessToken}", "kakao") + viewModel.postLogin(loginRequest) } - NaverIdLoginSDK.authenticate(this, oauthLoginCallback) - //네이버 토큰 임시확인용 - Log.i("NAVER-LOGIN","${NaverIdLoginSDK.getAccessToken()}") } - binding.loginKakaoBtn.setOnClickListener { - val callback: (OAuthToken?, Throwable?) -> Unit = { token, error -> + //카톡 연결이 없으면 카카오계정으로 로그인 + if (UserApiClient.instance.isKakaoTalkLoginAvailable(this)) { + UserApiClient.instance.loginWithKakaoTalk(this) { token, error -> if (error != null) { - Log.e("카카오로그인", "카카오계정으로 로그인 실패", error) + Log.e("카카오로그인", "카카오톡으로 로그인 실패", error) + if (error is ClientError && error.reason == ClientErrorCause.Cancelled) { + //디바이스 권한 요청 화면에서 로그인 취소할 경우 + //의도적 로그인 취소로 확인 > 로그인 시도 없이 back 처리 + return@loginWithKakaoTalk + } + //카톡 연결이 없으면 카카오계정으로 로그인 + UserApiClient.instance.loginWithKakaoAccount(this, callback = callback) } else if (token != null) { - Log.i("카카오로그인", "카카오계정으로 로그인 성공") + Log.i("카카오로그인", "카카오톡으로 로그인 성공") val loginRequest = LoginRequest("${token.accessToken}", "kakao") + //임시 토큰확인용 + Log.i("KAKAO-LOGIN","${token.accessToken}") viewModel.postLogin(loginRequest) } } - - //카톡 연결이 없으면 카카오계정으로 로그인 - if (UserApiClient.instance.isKakaoTalkLoginAvailable(this)) { - UserApiClient.instance.loginWithKakaoTalk(this) { token, error -> - if (error != null) { - Log.e("카카오로그인", "카카오톡으로 로그인 실패", error) - if (error is ClientError && error.reason == ClientErrorCause.Cancelled) { - //디바이스 권한 요청 화면에서 로그인 취소할 경우 - //의도적 로그인 취소로 확인 > 로그인 시도 없이 back 처리 - return@loginWithKakaoTalk - } - //카톡 연결이 없으면 카카오계정으로 로그인 - UserApiClient.instance.loginWithKakaoAccount(this, callback = callback) - } else if (token != null) { - Log.i("카카오로그인", "카카오톡으로 로그인 성공") - val loginRequest = LoginRequest("${token.accessToken}", "kakao") - //임시 토큰확인용 - Log.i("KAKAO-LOGIN","${token.accessToken}") - viewModel.postLogin(loginRequest) - } - } - } else { - UserApiClient.instance.loginWithKakaoAccount(this, callback = callback) - } + } else { + UserApiClient.instance.loginWithKakaoAccount(this, callback = callback) } } - companion object{ - var loginActivity:LoginActivity?=null - } - private fun startactivity() { // 회원가입 만들기용 임시 // val intent = Intent(this, SignupActivity::class.java) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/login/LoginViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/login/LoginViewModel.kt index e675e28a..e5685a91 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/login/LoginViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/login/LoginViewModel.kt @@ -34,8 +34,8 @@ class LoginViewModel @Inject constructor( .onSuccess { TtoklipApplication.prefs.setString("jwt",it.jwtToken) TtoklipApplication.prefs.setBoolean("isFirstLogin",it.ifFirstLogin) - _isFirstLogin.value=it.ifFirstLogin - _isLogin.value=true + _isFirstLogin.emit(it.ifFirstLogin) + _isLogin.emit(true) }.onFail { Log.d("LOGIN-API", "login 실패") } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/ManageMyInfoActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/ManageMyInfoActivity.kt index 4cd7df55..442eb866 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/ManageMyInfoActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/ManageMyInfoActivity.kt @@ -5,6 +5,7 @@ import android.content.ContentResolver import android.content.ContentUris import android.content.Context import android.content.Intent +import android.database.Cursor import android.graphics.Bitmap import android.graphics.Rect import android.graphics.drawable.Drawable @@ -28,10 +29,12 @@ import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.transition.Transition import com.google.android.material.chip.Chip import com.umc.ttoklip.R +import com.umc.ttoklip.TtoklipApplication import com.umc.ttoklip.databinding.ActivityManageMyInfoBinding import com.umc.ttoklip.presentation.base.BaseActivity import com.umc.ttoklip.presentation.honeytip.write.WriteHoneyTipActivity import com.umc.ttoklip.presentation.mypage.vm.ManageMyInfoViewModel +import com.umc.ttoklip.presentation.signup.SignupActivity import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -75,6 +78,7 @@ class ManageMyInfoActivity : binding.vm = viewModel initViewListener() viewModel.getMyPageInfo() + Log.d("jwt", TtoklipApplication.prefs.getString("jwt","")) } private fun initViewListener() { @@ -138,6 +142,8 @@ class ManageMyInfoActivity : val categories = category.map { it -> tabTextToCategory(it) } Log.d("categories", categories.toString()) Log.d("imageRequest", imageRequest.toString()) + Log.d("EditInfo",address+" "+binding.inputNicknameEt.text.toString()+" "+categories.toString()+" "+imageRequest+" "+independentYear+" "+independentMonth) + //카테고리 설정이 비는 게 문제임 자고일어나서 고치기 viewModel.editMyPageInfo( address, locationX, @@ -148,8 +154,8 @@ class ManageMyInfoActivity : independentYear, independentMonth ) val delete = deleteImage(tempImage) - //Log.d("delete", delete.toString()) - //finish() + Log.d("delete", delete.toString()) + finish() } binding.manageProfileImg.setOnClickListener { @@ -181,9 +187,11 @@ class ManageMyInfoActivity : inputIndependentCareerEt.text = "${it.independentYear}년 ${it.independentMonth}개월" inputAddressTv.text = it.street + address= it.street.toString() independentYear = it.independentYear independentMonth = it.independentMonth convertURLtoURI(it.profileImage) + Log.d("image",it.profileImage.toString()) Glide.with(this@ManageMyInfoActivity) .load(it.profileImage) .into(binding.manageProfileImg) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/ManageUsageActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/ManageUsageActivity.kt index 6300deab..a0a4b8bf 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/ManageUsageActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/ManageUsageActivity.kt @@ -1,6 +1,7 @@ package com.umc.ttoklip.presentation.mypage import android.view.View +import androidx.activity.viewModels import androidx.recyclerview.widget.LinearLayoutManager import com.umc.ttoklip.R import com.umc.ttoklip.databinding.ActivityManageUsageBinding @@ -9,11 +10,15 @@ import com.umc.ttoklip.presentation.mypage.adapter.BlockUser import com.umc.ttoklip.presentation.mypage.adapter.BlockUserAdapter import com.umc.ttoklip.presentation.mypage.adapter.Suspension import com.umc.ttoklip.presentation.mypage.adapter.SuspensionAdapter +import com.umc.ttoklip.presentation.mypage.vm.UsageViewModel import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class ManageUsageActivity : BaseActivity(R.layout.activity_manage_usage) { + + private val viewModel: UsageViewModel by viewModels() + private val suspensionAdapter by lazy { SuspensionAdapter() } @@ -23,15 +28,15 @@ class ManageUsageActivity : } override fun initView() { - val dummy = listOf(Suspension("이용 정지 5일", "부적절한 공구 참여로 이용이 정지되었습니다.", "12/12 ~ 12/16")) +// val dummy = listOf(Suspension("이용 정지 5일", "부적절한 공구 참여로 이용이 정지되었습니다.", "12/12 ~ 12/16")) binding.suspensionRv.adapter = suspensionAdapter binding.suspensionRv.layoutManager = LinearLayoutManager(this) - suspensionAdapter.submitList(dummy) + suspensionAdapter.submitList(viewModel.restrictList.value) - val dummy2 = listOf(BlockUser(null, "똑리비")) +// val dummy2 = listOf(BlockUser(null, "똑리비")) binding.blockUserRv.adapter = blockAdapter binding.blockUserRv.layoutManager = LinearLayoutManager(this) - blockAdapter.submitList(dummy2) + blockAdapter.submitList(viewModel.blockList.value) binding.manageUsageBackBtn.setOnClickListener { this.onBackPressedDispatcher.onBackPressed() diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyHoneyTipActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyHoneyTipActivity.kt index aaa6f4a7..2bdc8923 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyHoneyTipActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyHoneyTipActivity.kt @@ -12,7 +12,7 @@ import com.umc.ttoklip.R import com.umc.ttoklip.data.model.honeytip.HoneyTipMain import com.umc.ttoklip.databinding.ActivityMyHoneyTipBinding import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.hometown.ReadCommunicationActivity +import com.umc.ttoklip.presentation.hometown.communication.read.ReadCommunicationActivity import com.umc.ttoklip.presentation.honeytip.adapter.HoneyTipListRVA import com.umc.ttoklip.presentation.honeytip.adapter.OnItemClickListener import com.umc.ttoklip.presentation.honeytip.read.ReadHoneyTipActivity diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyInfoLocationActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyInfoLocationActivity.kt index edea5c98..ed3b6d2a 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyInfoLocationActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyInfoLocationActivity.kt @@ -18,6 +18,7 @@ import com.naver.maps.map.NaverMap import com.naver.maps.map.OnMapReadyCallback import com.naver.maps.map.UiSettings import com.naver.maps.map.overlay.CircleOverlay +import com.naver.maps.map.overlay.Marker import com.naver.maps.map.util.FusedLocationSource import com.umc.ttoklip.R import com.umc.ttoklip.databinding.ActivityMyinfoLocationBinding @@ -32,7 +33,7 @@ class MyInfoLocationActivity : private lateinit var naverMap: NaverMap private lateinit var locationSource: FusedLocationSource private lateinit var uiSetting: UiSettings - private lateinit var address: String + private var address: String="" private val LOCATION_PERMISSION_REQUEST_CODE: Int = 5000 private val PERMISSIONS = arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, @@ -40,6 +41,7 @@ class MyInfoLocationActivity : ) private lateinit var range: String private lateinit var circle: CircleOverlay + private lateinit var marker: Marker private var locationok: Boolean = false @@ -50,6 +52,7 @@ class MyInfoLocationActivity : } initMapView() circle = CircleOverlay() + marker=Marker() range = getString(R.string.range_500m) binding.locationRangeDescTv.text = @@ -116,25 +119,26 @@ class MyInfoLocationActivity : uiSetting.isLocationButtonEnabled = false binding.locationNowLocation.map = naverMap -// locationSource = - naverMap.locationSource = FusedLocationSource(this, LOCATION_PERMISSION_REQUEST_CODE) + locationSource = FusedLocationSource(this, LOCATION_PERMISSION_REQUEST_CODE) + naverMap.locationSource = locationSource naverMap.locationTrackingMode = LocationTrackingMode.Follow -// naverMap.locationOverlay.subIcon = -// OverlayImage.fromResource(com.naver.maps.map.R.drawable.navermap_location_overlay_icon) - - naverMap.addOnLocationChangeListener { - locationX=it.latitude.toInt() - locationY=it.longitude.toInt() - getAddress( - it.latitude, - it.longitude - ) - circle.center = LatLng(it.latitude, it.longitude) - locationok = true - setcircle() + + naverMap.setOnMapClickListener { pointF, latLng -> + setlocation(latLng.latitude,latLng.longitude) } } + private fun setlocation(latitude:Double,longitude:Double){ + this.address="" + getAddress(latitude, longitude) + circle.center = LatLng(latitude, longitude) + marker.position=LatLng(latitude,longitude) + locationok = true + setcircle() + marker.map=null + marker.map=naverMap + } + private fun setcircle() { if (range == "500m") circle.radius = 500.0 else if (range == "1km") circle.radius = 1000.0 @@ -169,16 +173,22 @@ class MyInfoLocationActivity : if (addressList != null && addressList.isNotEmpty()) { val address: Address = addressList[0] val spliteAddr = address.getAddressLine(0).split(" ") - this.address = spliteAddr[1] + " " + spliteAddr[2] + " " + spliteAddr[3] + for(i in 1.. spliteAddr.size-1){ + this.address=this.address+spliteAddr[i]+" " + } } } else { val addresses = geocoder.getFromLocation(latitude, longitude, 1) if (addresses != null) { val spliteAddr = addresses[0].getAddressLine(0).split(" ") - this.address = spliteAddr[1] + " " + spliteAddr[2] + " " + spliteAddr[3] + for(i in 1.. spliteAddr.size-1){ + this.address=this.address+spliteAddr[i]+" " + } } } - binding.locationMytownDetailTv.text = address + if (address.isNotEmpty()){ + binding.locationMytownDetailTv.text = address + } } override fun initObserver() { diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyPageFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyPageFragment.kt index 80feefbd..038a19b3 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyPageFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/MyPageFragment.kt @@ -8,9 +8,13 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.bumptech.glide.Glide import com.umc.ttoklip.R +import com.umc.ttoklip.TtoklipApplication import com.umc.ttoklip.databinding.FragmentMyPageBinding +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.login.LoginActivity +import com.umc.ttoklip.presentation.mypage.dialog.LogoutDialog import com.umc.ttoklip.presentation.mypage.vm.ManageMyInfoViewModel import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -46,57 +50,61 @@ class MyPageFragment : BaseFragment(R.layout.fragment_my_ binding.noticeBtn.setOnClickListener { startActivity(AlarmActivity.newIntent(requireContext())) } - binding.updateProfileBtn.setOnClickListener { + binding.updateProfileBtn.setOnClickListener { //카테고리 받아와야 제대로 업데이트 가능 val intent = Intent(requireContext(), ManageMyInfoActivity::class.java) startActivity(intent) } - binding.announcementFrame.setOnClickListener { - val intent = Intent(requireContext(), SetAnnouncementActivity::class.java) + binding.manageAccountFrame.setOnClickListener { //계정정보 화면 새로 만들 필요 있음 + val intent = Intent(requireContext(), ManageMyInfoActivity::class.java) startActivity(intent) } - binding.usageManageFrame.setOnClickListener { - val intent = Intent(requireContext(), ManageUsageActivity::class.java) + binding.announcementFrame.setOnClickListener { //공지사항 두 개만 넣어달라, api 연결은 해놨음 + val intent = Intent(requireContext(), SetAnnouncementActivity::class.java) startActivity(intent) } - binding.manageAccountFrame.setOnClickListener { - val intent = Intent(requireContext(), ManageMyInfoActivity::class.java) + binding.usageManageFrame.setOnClickListener { //api 연결은 해놨음 + val intent = Intent(requireContext(), ManageUsageActivity::class.java) startActivity(intent) } - binding.noticeFrame.setOnClickListener { - val intent = Intent(requireContext(), NoticeSettingActivity::class.java) + binding.customerServiceCenterFrame.setOnClickListener { //고객센터-faq 불러오기 연동 필요, 1:1 문의 보내기 필요 + val intent = Intent(requireContext(), CustomerServiceCenterActivity::class.java) startActivity(intent) } - binding.customerServiceCenterFrame.setOnClickListener { - val intent = Intent(requireContext(), CustomerServiceCenterActivity::class.java) + binding.noticeFrame.setOnClickListener {//알림 설정-알림이 되어야함 + val intent = Intent(requireContext(), NoticeSettingActivity::class.java) startActivity(intent) } - binding.termsPolicesFrame.setOnClickListener { + binding.termsPolicesFrame.setOnClickListener {//약관 및 정책 val intent = Intent(requireContext(), TermsPolicesActivity::class.java) startActivity(intent) } binding.logoutFrame.setOnClickListener { -// val dialog = LogoutDialog() -// dialog.show(parentFragmentManager, dialog.tag) + //로그아웃 다이얼로그 체크 + val dialog = LogoutDialog(logout = { + TtoklipApplication.prefs.removeString("jwt") + startActivity(Intent(activity,LoginActivity::class.java)) + activity?.finish() + }) + dialog.show(parentFragmentManager, dialog.tag) } - binding.transactionHistoryBtn.setOnClickListener { - val intent = Intent(requireContext(), TransactionHistoryActivity::class.java) - startActivity(intent) + binding.transactionHistoryBtn.setOnClickListener { //거래내역 + startActivity(TransactionHistoryActivity.newIntent(requireContext(),1,"")) } - binding.scrapBtn.setOnClickListener { + binding.scrapBtn.setOnClickListener { //스크랩 val intent = Intent(requireContext(), SavedHoneyTipActivity::class.java) startActivity(intent) } - binding.myHoneyTipBtn.setOnClickListener { + binding.myHoneyTipBtn.setOnClickListener { //꿀팁 val intent = Intent(requireContext(), MyHoneyTipActivity::class.java) startActivity(intent) } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/NoticeSettingActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/NoticeSettingActivity.kt index 09f10a52..0c4a761f 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/NoticeSettingActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/NoticeSettingActivity.kt @@ -3,6 +3,7 @@ package com.umc.ttoklip.presentation.mypage import com.umc.ttoklip.R import com.umc.ttoklip.databinding.ActivityNoticeSettingBinding import com.umc.ttoklip.presentation.base.BaseActivity +import dagger.hilt.android.AndroidEntryPoint class NoticeSettingActivity : BaseActivity(R.layout.activity_notice_setting) { diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/SavedHoneyTipActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/SavedHoneyTipActivity.kt index 888fd80f..96fac0d7 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/SavedHoneyTipActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/SavedHoneyTipActivity.kt @@ -13,7 +13,7 @@ import com.umc.ttoklip.R import com.umc.ttoklip.data.model.mypage.ScrapResponse import com.umc.ttoklip.databinding.ActivitySavedHoneyTipBinding import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.hometown.ReadCommunicationActivity +import com.umc.ttoklip.presentation.hometown.communication.read.ReadCommunicationActivity import com.umc.ttoklip.presentation.honeytip.read.ReadHoneyTipActivity import com.umc.ttoklip.presentation.mypage.adapter.OnSpinnerItemClickListener import com.umc.ttoklip.presentation.mypage.adapter.SavedHoneyTipAdapter diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/SetAnnouncementActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/SetAnnouncementActivity.kt index 9a05005b..a20c1d8f 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/SetAnnouncementActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/SetAnnouncementActivity.kt @@ -1,44 +1,47 @@ package com.umc.ttoklip.presentation.mypage +import androidx.activity.viewModels import androidx.recyclerview.widget.LinearLayoutManager import com.umc.ttoklip.R import com.umc.ttoklip.databinding.ActivitySetAnnouncementBinding import com.umc.ttoklip.presentation.base.BaseActivity -import com.umc.ttoklip.presentation.mypage.adapter.Announcement import com.umc.ttoklip.presentation.mypage.adapter.AnnouncementAdapter -import com.umc.ttoklip.presentation.mypage.adapter.AnnouncementContent -import com.umc.ttoklip.presentation.mypage.adapter.AnnouncementContentDetail +import com.umc.ttoklip.presentation.mypage.vm.NoticeViewModel import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class SetAnnouncementActivity : BaseActivity(R.layout.activity_set_announcement) { - override fun initObserver() = Unit + + private val vm:NoticeViewModel by viewModels() private val adapter by lazy { AnnouncementAdapter() } override fun initView() { - val dummy = listOf( - Announcement( - "12/12 ~ 12/16 ", "똑리비들을 위한 새로운 버전 업데이트 1.0.1", listOf( - AnnouncementContent( - "일부 오류를 수정하였어요", - listOf( - AnnouncementContentDetail("일부 기기에서 댓글 달기를 하면 어플이 비정상적으로 종료되는 오류를 수정하였습니다."), - AnnouncementContentDetail("일부 기사를 로딩할 때, 걸리는 로딩 시간을 단축시켰습니다.") - ) - ) - ) - ) - ) +// val dummy = listOf( +// Announcement( +// "12/12 ~ 12/16 ", "똑리비들을 위한 새로운 버전 업데이트 1.0.1", listOf( +// AnnouncementContent( +// "일부 오류를 수정하였어요", +// listOf( +// AnnouncementContentDetail("일부 기기에서 댓글 달기를 하면 어플이 비정상적으로 종료되는 오류를 수정하였습니다."), +// AnnouncementContentDetail("일부 기사를 로딩할 때, 걸리는 로딩 시간을 단축시켰습니다.") +// ) +// ) +// ) +// ) +// ) + vm.getNotice() binding.announcementsRv.adapter = adapter binding.announcementsRv.layoutManager = LinearLayoutManager(this) - adapter.submitList(dummy) + adapter.submitList(vm.noticeList.value) binding.setAnnouncementBackBtn.setOnClickListener { this.onBackPressedDispatcher.onBackPressed() } } + + override fun initObserver()=Unit } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/TransactionHistoryActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/TransactionHistoryActivity.kt index 08672c39..3dd62971 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/TransactionHistoryActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/TransactionHistoryActivity.kt @@ -1,18 +1,34 @@ package com.umc.ttoklip.presentation.mypage +import android.content.Context +import android.content.Intent +import androidx.activity.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.umc.ttoklip.R import com.umc.ttoklip.data.model.town.Togethers import com.umc.ttoklip.databinding.ActivityTransactionHistoryBinding import com.umc.ttoklip.presentation.base.BaseActivity +import com.umc.ttoklip.presentation.hometown.together.read.ReadTogetherActivity import com.umc.ttoklip.presentation.mypage.adapter.OnTogetherItemClickListener import com.umc.ttoklip.presentation.mypage.adapter.TransactionAdapter +import com.umc.ttoklip.presentation.mypage.vm.HistoryViewModel +import com.umc.ttoklip.presentation.otheruser.OtherTipActivity +import com.umc.ttoklip.presentation.otheruser.OtherTipActivity.Companion.OTHERID +import com.umc.ttoklip.presentation.otheruser.OtherTipActivity.Companion.OTHERNAME import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch @AndroidEntryPoint class TransactionHistoryActivity : BaseActivity(R.layout.activity_transaction_history), OnTogetherItemClickListener { + + private val viewModel: HistoryViewModel by viewModels() + private val adapter by lazy { TransactionAdapter(this, this) } @@ -22,13 +38,60 @@ class TransactionHistoryActivity : binding.transactionHistoryRv.adapter = adapter binding.transactionHistoryRv.layoutManager = LinearLayoutManager(this) + if (intent.getIntExtra(MYOROTEHR, 1) == 1) { + viewModel.getMyHistories() + } else { + + } + binding.myTransactionHistoryBackBtn.setOnClickListener { onBackPressedDispatcher.onBackPressed() } + + binding.transactionHistoryRv.addOnScrollListener(object : RecyclerView.OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + super.onScrollStateChanged(recyclerView, newState) + val lastVisibleItemPosition = + (recyclerView.layoutManager as LinearLayoutManager?)!!.findLastCompletelyVisibleItemPosition() + val totalItemViewCount = recyclerView.adapter!!.itemCount - 1 + + if (newState == 2 && !recyclerView.canScrollVertically(1) + && lastVisibleItemPosition == totalItemViewCount + ) { + if (intent.getIntExtra(MYOROTEHR, 1) == 1) { + viewModel.getMyHistories() + } else { + + } + } + } + + }) + } - override fun initObserver() = Unit + override fun initObserver() { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED){ + viewModel.histories.collect{ + adapter.submitList(it) + } + } + } + } override fun onClick(together: Togethers) { + val intent = Intent(this, ReadTogetherActivity::class.java) + intent.putExtra("postId", together.id) + startActivity(intent) + } + companion object { + const val MYOROTEHR = "my_or_other" // 1 :me 2: other + const val NAME = "other_name" + fun newIntent(context: Context, id: Int, user: String) = + Intent(context, TransactionHistoryActivity::class.java).apply { + putExtra(MYOROTEHR, id) + putExtra(NAME, user) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/Announcement.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/Announcement.kt deleted file mode 100644 index 6723de36..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/Announcement.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.umc.ttoklip.presentation.mypage.adapter - -data class Announcement( - val date: String, - val title: String, - val announcement: List, - var visibility: Boolean = false -) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementAdapter.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementAdapter.kt index d4722aae..cc33eefa 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementAdapter.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementAdapter.kt @@ -8,26 +8,26 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.umc.ttoklip.R +import com.umc.ttoklip.data.model.mypage.NoticeDetail +import com.umc.ttoklip.data.model.mypage.NoticeResponse import com.umc.ttoklip.databinding.ItemAnnouncementsBinding class AnnouncementAdapter : - ListAdapter(diff) { + ListAdapter(diff) { inner class AnnouncementViewHolder( private val binding: ItemAnnouncementsBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: Announcement) { + fun bind(data: NoticeDetail) { binding.announcementTitleTv.text = data.title - val adapter = AnnouncementContentAdapter() - binding.announcementContentRv.adapter = adapter - adapter.submitList(data.announcement) + binding.announcementDetailTv.text=data.content binding.announcementVisibilityBtn.setOnClickListener { if (data.visibility) { - binding.announcementContentFrame.visibility = View.GONE + binding.announcementDetailSv.visibility = View.GONE binding.announcementVisibilityBtn.setImageResource(R.drawable.ic_arrow_down_24) } else { - binding.announcementContentFrame.visibility = View.VISIBLE + binding.announcementDetailSv.visibility = View.VISIBLE binding.announcementVisibilityBtn.setImageResource(R.drawable.ic_arrow_up_24) } data.visibility = data.visibility.not() @@ -41,10 +41,7 @@ class AnnouncementAdapter : parent, false ) - binding.announcementContentRv.layoutManager = LinearLayoutManager(parent.context) - return AnnouncementViewHolder( - binding - ) + return AnnouncementViewHolder(binding) } override fun onBindViewHolder(holder: AnnouncementViewHolder, position: Int) { @@ -52,17 +49,17 @@ class AnnouncementAdapter : } companion object { - val diff = object : DiffUtil.ItemCallback() { + val diff = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: Announcement, - newItem: Announcement + oldItem: NoticeDetail, + newItem: NoticeDetail ): Boolean { - return oldItem.announcement == newItem.announcement + return oldItem.content == newItem.content } override fun areContentsTheSame( - oldItem: Announcement, - newItem: Announcement + oldItem: NoticeDetail, + newItem: NoticeDetail ): Boolean { return oldItem == newItem } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContent.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContent.kt deleted file mode 100644 index 83a69602..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContent.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.umc.ttoklip.presentation.mypage.adapter - -data class AnnouncementContent( - val title: String, - val contents: List -) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContentAdapter.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContentAdapter.kt deleted file mode 100644 index b24f0b33..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContentAdapter.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.umc.ttoklip.presentation.mypage.adapter - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.ListAdapter -import androidx.recyclerview.widget.RecyclerView -import com.umc.ttoklip.databinding.ItemAnnouncementContentBinding - -class AnnouncementContentAdapter : - ListAdapter(diff) { - inner class AnnouncementContentViewHolder( - private val binding: ItemAnnouncementContentBinding - ) : RecyclerView.ViewHolder(binding.root) { - - fun bind(data: AnnouncementContent) { - binding.announcementContentTitleTv.text = data.title - val adapter = AnnouncementContentDetailAdapter() - binding.announcementContentDetailRv.adapter = adapter - adapter.submitList(data.contents) - } - } - - override fun onCreateViewHolder( - parent: ViewGroup, - viewType: Int - ): AnnouncementContentViewHolder { - val binding = ItemAnnouncementContentBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ) - binding.announcementContentDetailRv.layoutManager = LinearLayoutManager(parent.context) - return AnnouncementContentViewHolder( - binding - ) - } - - override fun onBindViewHolder(holder: AnnouncementContentViewHolder, position: Int) { - holder.bind(getItem(position)) - } - - companion object { - val diff = object : DiffUtil.ItemCallback() { - override fun areItemsTheSame( - oldItem: AnnouncementContent, - newItem: AnnouncementContent - ): Boolean { - return oldItem.title == newItem.title - } - - override fun areContentsTheSame( - oldItem: AnnouncementContent, - newItem: AnnouncementContent - ): Boolean { - return oldItem == newItem - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContentDetail.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContentDetail.kt deleted file mode 100644 index 9c929027..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContentDetail.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.umc.ttoklip.presentation.mypage.adapter - -data class AnnouncementContentDetail( - val content: String -) \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContentDetailAdapter.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContentDetailAdapter.kt deleted file mode 100644 index 7dc2250e..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/AnnouncementContentDetailAdapter.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.umc.ttoklip.presentation.mypage.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.umc.ttoklip.databinding.ItemAnnouncementContentDetailBinding - -class AnnouncementContentDetailAdapter : - ListAdapter(diff) { - inner class DetailViewHolder( - private val binding: ItemAnnouncementContentDetailBinding - ) : RecyclerView.ViewHolder(binding.root) { - - fun bind(data: AnnouncementContentDetail) { - - binding.announcementContentDetailTv.text = data.content - } - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DetailViewHolder { - return DetailViewHolder( - ItemAnnouncementContentDetailBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ) - ) - } - - override fun onBindViewHolder(holder: DetailViewHolder, position: Int) { - holder.bind(getItem(position)) - } - - companion object { - val diff = object : DiffUtil.ItemCallback() { - override fun areItemsTheSame( - oldItem: AnnouncementContentDetail, - newItem: AnnouncementContentDetail - ): Boolean { - return oldItem.content == newItem.content - } - - override fun areContentsTheSame( - oldItem: AnnouncementContentDetail, - newItem: AnnouncementContentDetail - ): Boolean { - return oldItem == newItem - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/BlockUserAdapter.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/BlockUserAdapter.kt index 71472817..ee40fe7d 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/BlockUserAdapter.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/BlockUserAdapter.kt @@ -5,18 +5,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.model.mypage.BlockedUser +import com.umc.ttoklip.data.model.mypage.MyBlockUserResponse import com.umc.ttoklip.databinding.ItemBlockUserBinding -class BlockUserAdapter : ListAdapter(diff) { +class BlockUserAdapter : ListAdapter(diff) { inner class BlockUserViewHolder( private val binding: ItemBlockUserBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: BlockUser) { - data.imgUrl?.let { - - } + fun bind(data: BlockedUser) { +// data.imgUrl?.let { +// +// } binding.blockedUserId.text = data.userId binding.unblockBtn.setOnClickListener { @@ -39,17 +41,17 @@ class BlockUserAdapter : ListAdapter() { + val diff = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: BlockUser, - newItem: BlockUser + oldItem: BlockedUser, + newItem: BlockedUser ): Boolean { return oldItem.userId == newItem.userId } override fun areContentsTheSame( - oldItem: BlockUser, - newItem: BlockUser + oldItem: BlockedUser, + newItem: BlockedUser ): Boolean { return oldItem == newItem } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/SuspensionAdapter.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/SuspensionAdapter.kt index a0be5efd..a7d0fc83 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/SuspensionAdapter.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/SuspensionAdapter.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.mypage.RestrictedResponse import com.umc.ttoklip.databinding.ItemSuspensionHistoryBinding -class SuspensionAdapter : ListAdapter(diff) { +class SuspensionAdapter : ListAdapter(diff) { inner class SuspensionViewHolder( private val binding: ItemSuspensionHistoryBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: Suspension) { - binding.suspensionTitleTv.text = data.title + fun bind(data: RestrictedResponse) { + binding.suspensionTitleTv.text = data.type binding.suspensionReasonTv.text = data.reason - binding.suspensionPeriodTv.text = data.period + binding.suspensionPeriodTv.text = data.duration } } @@ -35,17 +36,17 @@ class SuspensionAdapter : ListAdapter() { + val diff = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: Suspension, - newItem: Suspension + oldItem: RestrictedResponse, + newItem: RestrictedResponse ): Boolean { - return oldItem.period == newItem.period + return oldItem.duration == newItem.duration } override fun areContentsTheSame( - oldItem: Suspension, - newItem: Suspension + oldItem: RestrictedResponse, + newItem: RestrictedResponse ): Boolean { return oldItem == newItem } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/TransactionAdapter.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/TransactionAdapter.kt index 043384d9..ec1b5928 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/TransactionAdapter.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/adapter/TransactionAdapter.kt @@ -43,10 +43,15 @@ class TransactionAdapter( val amount = context.getString(R.string.amount_format, currentAmount, targetAmount) val spannableAmount = SpannableString(amount) + + if (data.tradeStatus != "COMPLETED"){ + closureReasonChip.isGone = true + } + if (currentAmount == targetAmount) { spannableAmount.setSpan( ForegroundColorSpan(context.getColor(R.color.blue)), AMOUNT_STRING_START, - data.currentPrice.toString().length + AMOUNT_STRING_LENGTH, + currentAmount.toString().length, SPANNABLE_FLAG_ZERO ) transactionTitleTv.paintFlags = @@ -55,10 +60,9 @@ class TransactionAdapter( } else { spannableAmount.setSpan( ForegroundColorSpan(context.getColor(R.color.orange)), AMOUNT_STRING_START, - data.currentPrice.toString().length + AMOUNT_STRING_LENGTH, + currentAmount.toString().length, SPANNABLE_FLAG_ZERO ) - closureReasonChip.isGone = true } amountChip.text = spannableAmount @@ -75,7 +79,6 @@ class TransactionAdapter( transactionTitleTv.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG transactionTitleTv.setTextColor(context.getColor(R.color.gray60)) } else { - closureReasonChip.isGone = true spannableMember.setSpan( ForegroundColorSpan(context.getColor(R.color.orange)), AMOUNT_STRING_START, data.partyMax.toString().length, diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/vm/HistoryViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/vm/HistoryViewModel.kt new file mode 100644 index 00000000..30499d5b --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/vm/HistoryViewModel.kt @@ -0,0 +1,53 @@ +package com.umc.ttoklip.presentation.mypage.vm + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.mypage.ParticipatedDeal +import com.umc.ttoklip.data.model.mypage.ScrapResponse +import com.umc.ttoklip.data.model.town.Togethers +import com.umc.ttoklip.data.repository.mypage.MyPostRepository +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.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class HistoryViewModel @Inject constructor( + private val myPostRepository: MyPostRepository +) : ViewModel() { + private val isEnd = MutableStateFlow(false) + private val page = MutableStateFlow(0) + + private val _histories = MutableStateFlow(listOf()) + val histories: StateFlow> + get() = _histories + + fun getMyHistories() { + if (!isEnd.value) { + viewModelScope.launch { + try { + myPostRepository.getMyTogethers( + page = page.value + ).onSuccess { + _histories.emit(histories.value + it.carts) + page.value = page.value + 1 + isEnd.value = it.isLast + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/vm/NoticeViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/vm/NoticeViewModel.kt new file mode 100644 index 00000000..91656eec --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/vm/NoticeViewModel.kt @@ -0,0 +1,31 @@ +package com.umc.ttoklip.presentation.mypage.vm + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.mypage.NoticeDetail +import com.umc.ttoklip.data.repository.mypage.MyPageRepository3Impl +import com.umc.ttoklip.module.onSuccess +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class NoticeViewModel @Inject constructor( + private val repository:MyPageRepository3Impl +): ViewModel() { + + private val _noticeList=MutableStateFlow>(listOf()) + val noticeList=_noticeList.asStateFlow() + + fun getNotice(){ + viewModelScope.launch { + repository.getNotice() + .onSuccess { + _noticeList.emit(it.notices) + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/mypage/vm/UsageViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/mypage/vm/UsageViewModel.kt new file mode 100644 index 00000000..fa967343 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/mypage/vm/UsageViewModel.kt @@ -0,0 +1,59 @@ +package com.umc.ttoklip.presentation.mypage.vm + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.mypage.BlockedUser +import com.umc.ttoklip.data.model.mypage.RestrictedResponse +import com.umc.ttoklip.data.repository.mypage.MyPageRepository3Impl +import com.umc.ttoklip.module.onError +import com.umc.ttoklip.module.onSuccess +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class UsageViewModel @Inject constructor( + private val repository: MyPageRepository3Impl +):ViewModel(){ + + private val _restrictedList = MutableStateFlow>(listOf()) + val restrictList = _restrictedList.asStateFlow() + + private val _blockList = MutableStateFlow>(listOf()) + val blockList = _blockList.asStateFlow() + + fun getRestrict(){ + viewModelScope.launch { + repository.getRestrictedReason() + .onSuccess { +// _restrictedList.emit() + } + } + } + + fun getBlockUser(){ + viewModelScope.launch { + repository.getBlockedUser() + .onSuccess { + _blockList.emit(it.blockedUsers) + }.onError { + Log.d("error", it.toString()) + } + } + } + + fun unBlockUser(userId:Long){ + viewModelScope.launch { + repository.deleteBlockUser(userId) + .onSuccess { + getBlockUser() + }.onError { + Log.d("error",it.toString()) + } + } + } + +} \ No newline at end of file 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 b10004f0..d44361e6 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 @@ -12,7 +12,11 @@ import com.umc.ttoklip.data.model.news.comment.NewsCommentResponse import com.umc.ttoklip.databinding.ItemCommentBinding import com.umc.ttoklip.databinding.ItemReplyBinding -class CommentRVA(val replyComment: (Int) -> Unit, val ReportOrDelete: (Int, Boolean) -> Unit) : +class CommentRVA( + val replyComment: (Int) -> Unit, + val ReportOrDelete: (Int, Boolean) -> Unit, + val strangerOnClick: (String) -> Unit +) : ListAdapter(differ) { inner class ItemViewHolder( @@ -30,6 +34,9 @@ class CommentRVA(val replyComment: (Int) -> Unit, val ReportOrDelete: (Int, Bool data.writer == TtoklipApplication.prefs.getString("nickname", "") ) } + binding.profileImg.setOnClickListener { + strangerOnClick(data.writer ?: "") + } } } @@ -39,14 +46,18 @@ class CommentRVA(val replyComment: (Int) -> Unit, val ReportOrDelete: (Int, Bool fun bind(data: NewsCommentResponse) { binding.item = data - + Log.d("item", data.toString()) + Log.d("spf", TtoklipApplication.prefs.getString("nickname", "")) binding.deleteBtn.setOnClickListener { - Log.d("닉네임","${data.writer == TtoklipApplication.prefs.getString("nickname", "")}") + Log.d("닉네임", "${data.writer == TtoklipApplication.prefs.getString("nickname", "")}") ReportOrDelete( data.commentId, data.writer == TtoklipApplication.prefs.getString("nickname", "") ) } + binding.profileImg.setOnClickListener { + strangerOnClick(data.writer ?: "") + } } } 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 bd6a8c0a..67aa3bc4 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 @@ -12,10 +12,11 @@ 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.honeytip.dialog.DeleteDialogFragment -import com.umc.ttoklip.presentation.honeytip.dialog.ReportDialogFragment +import com.umc.ttoklip.presentation.dialog.DeleteDialogFragment +import com.umc.ttoklip.presentation.dialog.ReportDialogFragment import com.umc.ttoklip.presentation.news.adapter.CommentRVA import com.umc.ttoklip.presentation.news.adapter.PostImageRVA +import com.umc.ttoklip.presentation.otheruser.OtherUserActivity import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -50,6 +51,8 @@ class ArticleActivity : BaseActivity(R.layout.activity_a }) reportDialog.show(supportFragmentManager, reportDialog.tag) } + }, { nick -> + startActivity(OtherUserActivity.newIntent(this, nick)) }) } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherTipActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherTipActivity.kt new file mode 100644 index 00000000..c2bec9f6 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherTipActivity.kt @@ -0,0 +1,84 @@ +package com.umc.ttoklip.presentation.otheruser + +import android.content.Context +import android.content.Intent +import android.util.Log +import androidx.activity.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.umc.ttoklip.R +import com.umc.ttoklip.data.model.honeytip.HoneyTipMain +import com.umc.ttoklip.databinding.ActivityOtherHoneyTipBinding +import com.umc.ttoklip.presentation.base.BaseActivity +import com.umc.ttoklip.presentation.honeytip.adapter.HoneyTipListRVA +import com.umc.ttoklip.presentation.honeytip.adapter.OnItemClickListener +import com.umc.ttoklip.presentation.honeytip.read.ReadHoneyTipActivity +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class OtherTipActivity : + BaseActivity(R.layout.activity_other_honey_tip), + OnItemClickListener { + + private val viewModel: OtherTipViewModel by viewModels() + + private val adapter by lazy { + HoneyTipListRVA(this) + } + + override fun initView() { + binding.userT.text = intent.getStringExtra(OTHERNAME) ?: "USER" + binding.myHoneyTipRv.adapter = adapter + viewModel.getTips(intent.getIntExtra(OTHERID, 0)) + binding.myHoneyTipBackBtn.setOnClickListener { + finish() + } + + binding.myHoneyTipRv.addOnScrollListener(object : RecyclerView.OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + super.onScrollStateChanged(recyclerView, newState) + val lastVisibleItemPosition = + (recyclerView.layoutManager as LinearLayoutManager?)!!.findLastCompletelyVisibleItemPosition() + val totalItemViewCount = recyclerView.adapter!!.itemCount - 1 + + if (newState == 2 && !recyclerView.canScrollVertically(1) + && lastVisibleItemPosition == totalItemViewCount + ) { + viewModel.getTips(intent.getIntExtra(OTHERID, 0)) + } + } + + }) + } + + override fun initObserver() { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.tips.collect { tips -> + adapter.submitList(tips) + } + } + } + } + + override fun onClick(honeyTip: HoneyTipMain) { + val intent = Intent(this, ReadHoneyTipActivity::class.java) + intent.putExtra("postId", honeyTip.id) + startActivity(intent) + } + + companion object { + const val OTHERID = "other_id" + const val OTHERNAME = "other_name" + fun newIntent(context: Context, id: Int, user: String) = + Intent(context, OtherTipActivity::class.java).apply { + putExtra(OTHERID, id) + putExtra(OTHERNAME, user) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherTipViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherTipViewModel.kt new file mode 100644 index 00000000..2e05ce8c --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherTipViewModel.kt @@ -0,0 +1,64 @@ +package com.umc.ttoklip.presentation.otheruser + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.honeytip.HoneyTipMain +import com.umc.ttoklip.data.model.mypage.HoneyTip +import com.umc.ttoklip.data.repository.stranger.StrangerRepository +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.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class OtherTipViewModel @Inject constructor( + private val strangerRepository: StrangerRepository +) : ViewModel() { + + private val _tips = MutableStateFlow>(listOf()) + val tips: StateFlow> + get() = _tips + + private val isEnd = MutableStateFlow(false) + private val page = MutableStateFlow(0) + + fun getTips(id: Int) { + if (isEnd.value.not()) { + viewModelScope.launch { + try { + strangerRepository.getStrangerTip( + page = page.value, + id = id + ).onSuccess { + _tips.emit(tips.value + it.honeyTips.map { + HoneyTipMain( + it.id, + it.title, + it.content, + it.writer, + it.likeCount, + it.commentCount, + it.scrapCount, + "" + ) + }) + page.value = page.value + 1 + isEnd.value = it.isLast + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherUserActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherUserActivity.kt new file mode 100644 index 00000000..a34ff738 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherUserActivity.kt @@ -0,0 +1,40 @@ +package com.umc.ttoklip.presentation.otheruser + +import android.content.Context +import android.content.Intent +import androidx.activity.viewModels +import com.umc.ttoklip.R +import com.umc.ttoklip.databinding.ActivityOtheruserProfileBinding +import com.umc.ttoklip.presentation.base.BaseActivity +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class OtherUserActivity : + BaseActivity(R.layout.activity_otheruser_profile) { + + private val viewModel: OtherUserViewModel by viewModels() + + override fun initView() { + binding.vm = viewModel + viewModel.getStranger(intent.getStringExtra(OTHERUSER) ?: "") + + binding.otherprofileBackIb.setOnClickListener { + finish() + } + binding.otherprofileHoneytipCl.setOnClickListener { + startActivity(OtherTipActivity.newIntent(this, viewModel.strangerInfo.value.userId, viewModel.strangerInfo.value.nickname)) + } + } + + override fun initObserver() { + + } + + companion object { + const val OTHERUSER = "other_user" + fun newIntent(context: Context, user: String) = + Intent(context, OtherUserActivity::class.java).apply { + putExtra(OTHERUSER, user) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherUserViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherUserViewModel.kt new file mode 100644 index 00000000..46b11146 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtherUserViewModel.kt @@ -0,0 +1,44 @@ +package com.umc.ttoklip.presentation.otheruser + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.stranger.OtherUserInfoResponse +import com.umc.ttoklip.data.repository.stranger.StrangerRepository +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 OtherUserViewModel @Inject constructor( + private val strangerRepository: StrangerRepository +) : ViewModel() { + + private val _strangerInfo = MutableStateFlow(OtherUserInfoResponse()) + val strangerInfo: StateFlow + get() = _strangerInfo + + fun getStranger(nick : String){ + viewModelScope.launch(Dispatchers.IO) { + try { + strangerRepository.getStranger(nick) + .onSuccess { + _strangerInfo.emit(it) + }.onFail { + + }.onException { + throw it + } + } catch (e: Exception) { + e.printStackTrace() + Log.d("예외", "$e") + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtheruserActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtheruserActivity.kt deleted file mode 100644 index 3ca3b0ed..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtheruserActivity.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.umc.ttoklip.presentation.otheruser - -import com.umc.ttoklip.R -import com.umc.ttoklip.databinding.ActivityOtheruserProfileBinding -import com.umc.ttoklip.databinding.ActivitySignupBinding -import com.umc.ttoklip.presentation.base.BaseActivity - -class OtheruserActivity: BaseActivity(R.layout.activity_otheruser_profile) { - override fun initView() { - } - - override fun initObserver() { - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtheruserViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtheruserViewModel.kt deleted file mode 100644 index e21c1da7..00000000 --- a/app/src/main/java/com/umc/ttoklip/presentation/otheruser/OtheruserViewModel.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.umc.ttoklip.presentation.otheruser - -class OtheruserViewModel { - -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/search2/fragment/SearchTownFragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/search2/fragment/SearchTownFragment.kt index 88ef319a..2911598f 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/search2/fragment/SearchTownFragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/search2/fragment/SearchTownFragment.kt @@ -11,8 +11,7 @@ import androidx.recyclerview.widget.RecyclerView import com.umc.ttoklip.R import com.umc.ttoklip.databinding.FragmentItemSearchBinding import com.umc.ttoklip.presentation.base.BaseFragment -import com.umc.ttoklip.presentation.hometown.ReadCommunicationActivity -import com.umc.ttoklip.presentation.honeytip.read.ReadHoneyTipActivity +import com.umc.ttoklip.presentation.hometown.communication.read.ReadCommunicationActivity import com.umc.ttoklip.presentation.mypage.SortSpinnerAdapter import com.umc.ttoklip.presentation.news.detail.ArticleActivity import com.umc.ttoklip.presentation.search.adapter.SearchRVA 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 2effcbe0..8df2062c 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 @@ -38,46 +38,36 @@ class SignupViewModel @Inject constructor( private val signupRepository: SignupRepositoryImpl, application: Application ) : AndroidViewModel(application) { - private val _nickcheckbtn=MutableStateFlow(false) - val nickcheckbtn:StateFlow - get() = _nickcheckbtn - private val _nickok = MutableStateFlow(false) - val nickok: StateFlow - get() = _nickok - private var _independentCareerok = MutableStateFlow(false) - val independentCareerok: StateFlow - get() = _independentCareerok - private var _interestok = MutableStateFlow(false) - val interestok: StateFlow - get() = _interestok + val nickcheckbtn=MutableStateFlow(false) + val nickok = MutableStateFlow(false) + var independentCareerok = MutableStateFlow(false) + var interestok = MutableStateFlow(false) fun nickCheck(nick: String) { viewModelScope.launch { signupRepository.checkNickname(nick) .onSuccess { Log.i("nick check", "성공") - _nickok.value = true + nickok.emit(true) }.onFail { Log.d("nick check", "실패") - _nickok.value = false + nickok.emit(false) } } } fun nickcheckclick(){ viewModelScope.launch { - _nickcheckbtn.value=true + nickcheckbtn.emit(true) } } - fun independentCheck(indendentok: Boolean) { viewModelScope.launch { - _independentCareerok.value = indendentok + independentCareerok.emit(indendentok) } } - - fun interestCheck(interestok: Boolean) { + fun interestCheck(interestcheck: Boolean) { viewModelScope.launch { - _interestok.value = interestok + interestok.emit(interestcheck) } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup1Fragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup1Fragment.kt index 2011c5ec..d622d1d3 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup1Fragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup1Fragment.kt @@ -65,7 +65,7 @@ class Signup1Fragment: BaseFragment(R.layout.fragment_si bundle.putString("userName",binding.signup1NameEt.text.toString()) bundle.putString("userBirth",binding.signup1BirthEt.text.toString()) bundle.putString("userEmail",binding.signup1EmailEt.text.toString()) -// findNavController().navigate(R.id.action_signup1_fragment_to_signup2_fragment,bundle) + findNavController().navigate(R.id.action_signup1_fragment_to_signup2_fragment,bundle) } } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup2Fragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup2Fragment.kt index 838d813e..1e374227 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup2Fragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup2Fragment.kt @@ -96,7 +96,7 @@ class Signup2Fragment: BaseFragment(R.layout.fragment_si binding.signup2NextBtn.setOnClickListener { if(idok&&pwok){ val bundle=Bundle() -// findNavController().navigate(R.id.action_signup2_fragment_to_signup3_fragment) + findNavController().navigate(R.id.action_signup2_fragment_to_signup3_fragment) } } } diff --git a/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup3Fragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup3Fragment.kt index ef54da91..3dd9cdeb 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup3Fragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup3Fragment.kt @@ -69,7 +69,7 @@ class Signup3Fragment : BaseFragment(R.layout.fragment_s override fun initView() { val activity = activity as SignupActivity - activity?.setProg(1) + activity?.setProg(3) //약관 불러오기 viewModel.getTerm() diff --git a/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup4Fragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup4Fragment.kt index 56e7eee5..d313616e 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup4Fragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup4Fragment.kt @@ -16,6 +16,7 @@ import android.view.View import androidx.activity.result.PickVisualMediaRequest import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat +import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.Lifecycle @@ -28,11 +29,12 @@ import com.umc.ttoklip.R import com.umc.ttoklip.TtoklipApplication import com.umc.ttoklip.databinding.FragmentSignup4Binding import com.umc.ttoklip.presentation.base.BaseFragment -import com.umc.ttoklip.presentation.honeytip.dialog.ImageDialogFragment +import com.umc.ttoklip.presentation.dialog.ImageDialogFragment import com.umc.ttoklip.presentation.mypage.ChooseMainInterestDialogFragment import com.umc.ttoklip.presentation.mypage.InputIndependentCareerDialogFragment import com.umc.ttoklip.presentation.signup.SignupActivity import com.umc.ttoklip.presentation.signup.SignupViewModel +import com.umc.ttoklip.presentation.signup.location.LocationActivity import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -48,7 +50,7 @@ import java.net.URI @AndroidEntryPoint class Signup4Fragment : BaseFragment(R.layout.fragment_signup4) { - private val viewModel: SignupViewModel by viewModels() + private val viewModel: SignupViewModel by activityViewModels() private lateinit var interestArray: ArrayList private var independentCareerYear: Int? = null @@ -81,59 +83,21 @@ class Signup4Fragment : BaseFragment(R.layout.fragment_s override fun initView() { interestArray = ArrayList() val activity = activity as SignupActivity - activity?.setProg(2) + activity?.setProg(4) + + initIndependent() binding.signup4NickcheckButton.setOnClickListener { viewModel.nickCheck(binding.signup4NicknameEt.text.toString()) viewModel.nickcheckclick() } - if (independentCareerYear != null || independentCareerMonth != null) { - if (independentCareerYear != ZERO_CAREER && independentCareerMonth != ZERO_CAREER) { - binding.signup4IndependenceEt.text = - getString( - R.string.my_independent_career_base_format, - independentCareerYear, - independentCareerMonth - ) - } else if (independentCareerYear != ZERO_CAREER) { - binding.signup4IndependenceEt.text = - getString(R.string.my_independent_career_year_format, independentCareerYear) - } else if (independentCareerMonth != ZERO_CAREER) { - binding.signup4IndependenceEt.text = - getString(R.string.my_independent_career_month_format, independentCareerMonth) - } else { - binding.signup4IndependenceEt.text = - getString(R.string.my_independent_career_month_format, ZERO_CAREER) - } - binding.signup4IndependenceEt.setTextColor( - ContextCompat.getColor( - activity, - R.color.black - ) - ) - viewModel.independentCheck(true) - nextok() - } - binding.signup4IndependenceEt.setOnClickListener { viewModel.independentCheck(true) val bottomSheet = InputIndependentCareerDialogFragment { year, month -> - if (year != ZERO_CAREER && month != ZERO_CAREER) { - binding.signup4IndependenceEt.text = - getString(R.string.my_independent_career_base_format, year, month) - } else if (year != ZERO_CAREER) { - binding.signup4IndependenceEt.text = - getString(R.string.my_independent_career_year_format, year) - } else if (month != ZERO_CAREER) { - binding.signup4IndependenceEt.text = - getString(R.string.my_independent_career_month_format, month) - } else { - binding.signup4IndependenceEt.text = - getString(R.string.my_independent_career_month_format, ZERO_CAREER) - } independentCareerYear = year independentCareerMonth = month + initIndependent() } bottomSheet.show(activity.supportFragmentManager, bottomSheet.tag) binding.signup4IndependenceEt.setTextColor( @@ -191,23 +155,65 @@ class Signup4Fragment : BaseFragment(R.layout.fragment_s viewModel.interestok.value && viewModel.nickok.value ) { - val bundle = Bundle() - bundle.putString("nickname", binding.signup4NicknameEt.text.toString()) - bundle.putStringArrayList("interest", interestArray) - bundle.putString( - "imageUri", - if (imageSource.isNotEmpty()) imageSource - else "" -// Uri.fromFile(File("//android_asset/profile_image_default.png")).toString() - ) - bundle.putInt("independentCareerYear", independentCareerYear!!) - bundle.putInt("independentCareerMonth", independentCareerMonth!!) + val bundle=Bundle() + bundle.putString("nickname",viewModel.nickname.value) + bundle.putStringArrayList("interest",viewModel.categories.value) + bundle.putString("imageUri",viewModel.profileImage.value) + bundle.putInt("independentCareerYear",viewModel.independenctYear.value) + bundle.putInt("independentCareerMonth",viewModel.independenctMonth.value) + val intent=Intent(activity, LocationActivity::class.java) + intent.putExtra("userInfo",bundle) + startActivity(intent) + activity.finish() - findNavController().navigate( - R.id.action_signup4_fragment_to_signup5_fragment, - bundle - ) + //navigate to signup fragment 5 +// val bundle = Bundle() +// bundle.putString("nickname", binding.signup4NicknameEt.text.toString()) +// bundle.putStringArrayList("interest", interestArray) +// bundle.putString( +// "imageUri", +// if (imageSource.isNotEmpty()) imageSource +// else "" +//// Uri.fromFile(File("//android_asset/profile_image_default.png")).toString() +// ) +// bundle.putInt("independentCareerYear", independentCareerYear!!) +// bundle.putInt("independentCareerMonth", independentCareerMonth!!) +// +// findNavController().navigate( +// R.id.action_signup4_fragment_to_signup5_fragment, +// bundle +// ) + } + } + } + + private fun initIndependent(){ + if (independentCareerYear != null || independentCareerMonth != null) { + if (independentCareerYear != ZERO_CAREER && independentCareerMonth != ZERO_CAREER) { + binding.signup4IndependenceEt.text = + getString( + R.string.my_independent_career_base_format, + independentCareerYear, + independentCareerMonth + ) + } else if (independentCareerYear != ZERO_CAREER) { + binding.signup4IndependenceEt.text = + getString(R.string.my_independent_career_year_format, independentCareerYear) + } else if (independentCareerMonth != ZERO_CAREER) { + binding.signup4IndependenceEt.text = + getString(R.string.my_independent_career_month_format, independentCareerMonth) + } else { + binding.signup4IndependenceEt.text = + getString(R.string.my_independent_career_month_format, ZERO_CAREER) } + binding.signup4IndependenceEt.setTextColor( + ContextCompat.getColor( + requireActivity(), + R.color.black + ) + ) + viewModel.independentCheck(true) + nextok() } } @@ -225,17 +231,6 @@ class Signup4Fragment : BaseFragment(R.layout.fragment_s .circleCrop() .into(binding.signup4ProfileImageIv) imageSource = getRealPathFromUri(uri, context) -// val bitmap=MediaStore.Images.Media.getBitmap(context.contentResolver,uri) -// val resizeBitmap= Bitmap.createScaledBitmap(bitmap,bitmap.width/2,bitmap.height/2,true) -// val byteArrayOutputStream=ByteArrayOutputStream() -// resizeBitmap.compress(Bitmap.CompressFormat.JPEG,90,byteArrayOutputStream) -// val tempFile=File.createTempFile("resized_image",".jpg",context.cacheDir) -// val fileOutputStream=FileOutputStream(tempFile) -// fileOutputStream.write(byteArrayOutputStream.toByteArray()) -// fileOutputStream.close() -// imageSource=Uri.fromFile(tempFile).toString() -// Log.i("PhotoPicker", imageSource) -// imageSource=uri.toString() } else { Log.d("PhotoPicker", "No media selected") } @@ -268,62 +263,6 @@ class Signup4Fragment : BaseFragment(R.layout.fragment_s } return "" } -// fun getPath(context: Context, uri: Uri): String? { -// val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { -// if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { -// if (isExternalStorageDocument(uri)) { -// val docId = DocumentsContract.getDocumentId(uri) -// val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() } -// .toTypedArray() -// val type = split[0] -// if ("primary".equals(type, ignoreCase = true)) { -// return Environment.getExternalStorageDirectory().toString() + "/" + split[1] -// } -// } else if (isMediaDocument(uri)) { -// val docId = DocumentsContract.getDocumentId(uri) -// val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() } -// .toTypedArray() -// val type = split[0] -// var contentUri: Uri? = null -// contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI -// val selection = "_id=?" -// val selectionArgs = arrayOf( -// split[1] -// ) -// return getDataColumn(context, contentUri, selection, selectionArgs) -// } -// } -// } -// return null -// } -// fun isExternalStorageDocument(uri: Uri): Boolean { -// return "com.android.externalstorage.documents" == uri.authority -// } -// fun getDataColumn( -// context: Context, -// uri: Uri?, -// selection: String?, -// selectionArgs: Array? -// ): String? { -// var cursor: Cursor? = null -// val column = "_data" -// val projection = arrayOf(column) -// try { -// cursor = -// context.contentResolver.query(uri!!, projection, selection, selectionArgs, null) -// if (cursor != null && cursor.moveToFirst()) { -// val column_index = cursor.getColumnIndexOrThrow(column) -// return cursor.getString(column_index) -// } -// } finally { -// cursor?.close() -// } -// return null -// } -// fun isMediaDocument(uri: Uri): Boolean { -// return "com.android.providers.media.documents" == uri.authority -// } private fun nextok() { if (viewModel.nickok.value && diff --git a/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup5Fragment.kt b/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup5Fragment.kt index 8bbe77f8..29c000e4 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup5Fragment.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/signup/fragments/Signup5Fragment.kt @@ -4,6 +4,7 @@ import android.content.Intent import android.os.Bundle import android.widget.SeekBar import androidx.core.content.ContextCompat +import androidx.fragment.app.activityViewModels import com.umc.ttoklip.R import com.umc.ttoklip.databinding.FragmentSignup5Binding import com.umc.ttoklip.presentation.MainActivity @@ -12,9 +13,13 @@ import com.umc.ttoklip.presentation.login.LoginActivity import com.umc.ttoklip.presentation.signup.location.DirectLocationActivity import com.umc.ttoklip.presentation.signup.location.LocationActivity import com.umc.ttoklip.presentation.signup.SignupActivity +import com.umc.ttoklip.presentation.signup.SignupViewModel +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class Signup5Fragment: BaseFragment(R.layout.fragment_signup5) { + private val viewModel: SignupViewModel by activityViewModels() private lateinit var range: String override fun initObserver() { @@ -22,7 +27,7 @@ class Signup5Fragment: BaseFragment(R.layout.fragment_si override fun initView() { val activity=activity as SignupActivity - activity.setProg(3) + activity.setProg(5) range = getString(R.string.range_500m) binding.rangeSettingExplainTv.text = @@ -59,19 +64,18 @@ class Signup5Fragment: BaseFragment(R.layout.fragment_si }) binding.signup5LocationBtn.setOnClickListener { - val bbundle= requireArguments() - val abundle=Bundle() - abundle.putString("nickname",bbundle.getString("nickname")) - abundle.putStringArrayList("interest",bbundle.getStringArrayList("interest")) - abundle.putString("imageUri",bbundle.getString("imageUri")) - abundle.putInt("independentCareerYear",bbundle.getInt("independentCareerYear")) - abundle.putInt("independentCareerMonth",bbundle.getInt("independentCareerMonth")) + val bundle=Bundle() + bundle.putString("nickname",viewModel.nickname.value) + bundle.putStringArrayList("interest",viewModel.categories.value) + bundle.putString("imageUri",viewModel.profileImage.value) + bundle.putInt("independentCareerYear",viewModel.independenctYear.value) + bundle.putInt("independentCareerMonth",viewModel.independenctMonth.value) val intent=Intent(activity, LocationActivity::class.java) - intent.putExtra("userInfo",abundle) + intent.putExtra("userInfo",bundle) startActivity(intent) } binding.signup5LocationDirectEt.setOnClickListener { -// startActivity(Intent(activity, DirectLocationActivity::class.java)) + startActivity(Intent(activity, DirectLocationActivity::class.java)) } binding.signup5NextBtn.setOnClickListener { startActivity(Intent(activity, MainActivity::class.java)) diff --git a/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationActivity.kt index 384d402a..369d4edf 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationActivity.kt @@ -1,20 +1,21 @@ package com.umc.ttoklip.presentation.signup.location -import android.util.Log -import androidx.lifecycle.MutableLiveData +import androidx.activity.viewModels import com.umc.ttoklip.R -import com.umc.ttoklip.data.model.KakaoResponse import com.umc.ttoklip.databinding.ActivityDirectLocationBinding -import com.umc.ttoklip.di.KakaoModule import com.umc.ttoklip.presentation.base.BaseActivity -import retrofit2.Call -import retrofit2.Response +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class DirectLocationActivity : BaseActivity(R.layout.activity_direct_location) { - override fun initView() { + private val viewModel:DirectLocationViewModel by viewModels() + override fun initView() { + binding.directLocationSearchIv.setOnClickListener { + viewModel.searchAddress(binding.directLocationAddressEt.text.toString()) + } } override fun initObserver() { diff --git a/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationModelView.kt b/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationModelView.kt index a076e404..129cdb80 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationModelView.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationModelView.kt @@ -1,14 +1,6 @@ package com.umc.ttoklip.presentation.signup.location -import android.util.Log -import androidx.lifecycle.MutableLiveData -import com.umc.ttoklip.data.api.KakaoApi -import com.umc.ttoklip.data.model.KakaoResponse import com.umc.ttoklip.data.repository.location.DirectLocationRepositoryImpl -import com.umc.ttoklip.di.KakaoModule -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response class DirectLocationModelView( private val kakaoApi:DirectLocationRepositoryImpl diff --git a/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationViewModel.kt b/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationViewModel.kt index dcef4cf1..90233f36 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationViewModel.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/signup/location/DirectLocationViewModel.kt @@ -1,4 +1,39 @@ package com.umc.ttoklip.presentation.signup.location -class DirectLocationViewModel { +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.umc.ttoklip.data.model.KakaoResponse +import com.umc.ttoklip.data.repository.location.DirectLocationRepositoryImpl +import com.umc.ttoklip.module.onError +import com.umc.ttoklip.module.onFail +import com.umc.ttoklip.module.onSuccess +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class DirectLocationViewModel @Inject constructor( + private val directLocationRepository: DirectLocationRepositoryImpl +): ViewModel() { + + private var addressList_= MutableStateFlow>(ArrayList()) + val addressList:StateFlow> + get() = addressList_ + + fun searchAddress(address:String){ + viewModelScope.launch { + directLocationRepository.getDirectAddress(address) + .onSuccess { + addressList_.emit(it.documents as ArrayList) + Log.i("DirectLocation","장소 검색 성공"+addressList.value[0]) + }.onFail { + Log.i("DirectLocation","장소 검색 실패") + }.onError { + Log.d("DirectLocation","장소 검색 오류"+it) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/presentation/signup/location/LocationActivity.kt b/app/src/main/java/com/umc/ttoklip/presentation/signup/location/LocationActivity.kt index 740bb3be..e2fe3115 100644 --- a/app/src/main/java/com/umc/ttoklip/presentation/signup/location/LocationActivity.kt +++ b/app/src/main/java/com/umc/ttoklip/presentation/signup/location/LocationActivity.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.content.pm.PackageManager import android.location.Address import android.location.Geocoder +import android.location.LocationManager import android.os.Build import android.widget.SeekBar import androidx.activity.viewModels @@ -14,9 +15,11 @@ import com.naver.maps.geometry.LatLng import com.naver.maps.map.LocationTrackingMode import com.naver.maps.map.MapFragment import com.naver.maps.map.NaverMap +import com.naver.maps.map.NaverMapOptions import com.naver.maps.map.OnMapReadyCallback import com.naver.maps.map.UiSettings import com.naver.maps.map.overlay.CircleOverlay +import com.naver.maps.map.overlay.Marker import com.naver.maps.map.util.FusedLocationSource import com.umc.ttoklip.R import com.umc.ttoklip.databinding.ActivityLocationBinding @@ -38,7 +41,7 @@ class LocationActivity : private lateinit var naverMap: NaverMap private lateinit var locationSource: FusedLocationSource private lateinit var uiSetting: UiSettings - private lateinit var address: String + private var address: String="" private val LOCATION_PERMISSION_REQUEST_CODE: Int = 5000 private val PERMISSIONS = arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, @@ -46,6 +49,7 @@ class LocationActivity : ) private lateinit var range: String private lateinit var circle: CircleOverlay + private lateinit var marker: Marker private var locationok: Boolean = false @@ -56,6 +60,7 @@ class LocationActivity : } initMapView() circle = CircleOverlay() + marker=Marker() range = getString(R.string.range_500m) binding.locationRangeDescTv.text = @@ -96,6 +101,10 @@ class LocationActivity : } }) + binding.locationBackIb.setOnClickListener { + finish() + } + binding.locationNextBtn.setOnClickListener { if (locationok) { val bundle = intent.getBundleExtra("userInfo") @@ -125,24 +134,27 @@ class LocationActivity : uiSetting.isLocationButtonEnabled = false binding.locationNowLocation.map = naverMap -// locationSource = - naverMap.locationSource = FusedLocationSource(this, LOCATION_PERMISSION_REQUEST_CODE) + locationSource =FusedLocationSource(this, LOCATION_PERMISSION_REQUEST_CODE) + naverMap.locationSource = locationSource naverMap.locationTrackingMode = LocationTrackingMode.Follow -// naverMap.locationOverlay.subIcon = -// OverlayImage.fromResource(com.naver.maps.map.R.drawable.navermap_location_overlay_icon) - - naverMap.addOnLocationChangeListener { - getAddress( - it.latitude, - it.longitude - ) - circle.center = LatLng(it.latitude, it.longitude) - locationok = true - setcircle() - nextok() + + naverMap.setOnMapClickListener { pointF, latLng -> + setlocation(latLng.latitude,latLng.longitude) } } + private fun setlocation(latitude:Double,longitude:Double){ + this.address="" + getAddress(latitude, longitude) + circle.center = LatLng(latitude, longitude) + marker.position=LatLng(latitude,longitude) + locationok = true + setcircle() + marker.map=null + marker.map=naverMap + nextok() + } + private fun setcircle() { if (range == "500m") circle.radius = 500.0 else if (range == "1km") circle.radius = 1000.0 @@ -190,22 +202,21 @@ class LocationActivity : if (addressList != null && addressList.isNotEmpty()) { val address: Address = addressList[0] val spliteAddr = address.getAddressLine(0).split(" ") - this.address = spliteAddr[1] + " " + spliteAddr[2] + " " + spliteAddr[3] - }else{ - this.address = "" + for(i in 1.. spliteAddr.size-1){ + this.address=this.address+spliteAddr[i]+" " + } } } else { val addresses = geocoder.getFromLocation(latitude, longitude, 1) if (addresses != null) { val spliteAddr = addresses[0].getAddressLine(0).split(" ") - this.address = spliteAddr[1] + " " + spliteAddr[2] + " " + spliteAddr[3] - }else{ - this.address = "" + for(i in 1.. spliteAddr.size-1){ + this.address = this.address+spliteAddr[i]+" " + } } - } - if (::address.isInitialized){ - binding.locationMytownDetailTv.text = address ?:"" + if (address.isNotEmpty()){ + binding.locationMytownDetailTv.text = address } } 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 1bd2536d..70454dec 100644 --- a/app/src/main/java/com/umc/ttoklip/util/BindAdapter.kt +++ b/app/src/main/java/com/umc/ttoklip/util/BindAdapter.kt @@ -7,14 +7,9 @@ import android.widget.ImageView import android.widget.TextView import androidx.annotation.StyleRes import androidx.appcompat.widget.AppCompatTextView +import androidx.core.view.isVisible 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 @BindingAdapter("bindTextViewStyle") @@ -44,4 +39,31 @@ fun ImageView.setUrlImg(imageUrl: String?, placeholder: Drawable?) { @BindingAdapter("textInt") fun AppCompatTextView.textInt(int: Int) { this.text = int.toString() +} + +@BindingAdapter("bind:isWriter", "bind:isDeadLine") +fun TextView.setJoinFrameTextViewVisible(isWriter: Boolean, isDeadLine: Boolean) { + this.isVisible = if (isWriter) { + !isDeadLine + } else { + false + } +} + +@BindingAdapter("bind:joinVisible", "bind:isDeadLine") +fun TextView.setJoinBtnVisible(joinState: Boolean, isDeadLine: Boolean) { + this.isVisible = if (isDeadLine) { + false + } else { + joinState + } +} + +@BindingAdapter("bind:cancelJoinVisible", "bind:isDeadLine") +fun TextView.setCancelJoinBtnVisible(joinState: Boolean, isDeadLine: Boolean) { + this.isVisible = if (isDeadLine) { + false + } else { + !joinState + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/util/Extension.kt b/app/src/main/java/com/umc/ttoklip/util/Extension.kt new file mode 100644 index 00000000..2e983546 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/util/Extension.kt @@ -0,0 +1,37 @@ +package com.umc.ttoklip.util + +import android.content.Context +import android.net.Uri +import android.provider.OpenableColumns +import java.io.File +import java.io.FileOutputStream + +fun Context.uriToFile(uri: Uri): File { + val inputStream = contentResolver.openInputStream(uri) ?: return File("") + val file = File(cacheDir, getFileName(uri)) + val outputStream = FileOutputStream(file) + inputStream.copyTo(outputStream) + inputStream.close() + outputStream.close() + return file +} + +fun Context.getFileName(uri: Uri): String { + var result: String? = null + if (uri.scheme == "content") { + val cursor = contentResolver.query(uri, null, null, null, null) + cursor.use { + if (it != null && it.moveToFirst()) { + result = it.getString(it.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME)) + } + } + } + if (result == null) { + result = uri.path + val cut = result?.lastIndexOf('/') ?: -1 + if (cut != -1) { + result = result?.substring(cut + 1) + } + } + return result ?: "unknown" +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/util/NaverInterceptor.kt b/app/src/main/java/com/umc/ttoklip/util/NaverInterceptor.kt new file mode 100644 index 00000000..fdb21329 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/util/NaverInterceptor.kt @@ -0,0 +1,19 @@ +package com.umc.ttoklip.util + +import android.util.Log +import com.umc.ttoklip.R +import com.umc.ttoklip.TtoklipApplication +import okhttp3.Interceptor +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.Response + +class NaverInterceptor : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response = with(chain) { + val newRequest = request().newBuilder() + .addHeader("X-NCP-APIGW-API-KEY-ID", TtoklipApplication.getString(R.string.naver_client_key)) + .addHeader("X-NCP-APIGW-API-KEY", TtoklipApplication.getString(R.string.naver_client_secret_key)) + .build() + + proceed(newRequest) + } +} diff --git a/app/src/main/java/com/umc/ttoklip/util/PreferenceUtil.kt b/app/src/main/java/com/umc/ttoklip/util/PreferenceUtil.kt index 88f54d79..fbabfbd0 100644 --- a/app/src/main/java/com/umc/ttoklip/util/PreferenceUtil.kt +++ b/app/src/main/java/com/umc/ttoklip/util/PreferenceUtil.kt @@ -12,6 +12,9 @@ class PreferenceUtil(context:Context) { fun setString(key:String,str:String){ prefs.edit().putString(key,str).apply() } + fun removeString(key:String){ + prefs.edit().remove(key).apply() + } fun getBoolean(key:String,defValue:Boolean):Boolean{ return prefs.getBoolean(key,defValue) } diff --git a/app/src/main/java/com/umc/ttoklip/util/TtoklipFirebaseMessagingService.kt b/app/src/main/java/com/umc/ttoklip/util/TtoklipFirebaseMessagingService.kt new file mode 100644 index 00000000..d4010f07 --- /dev/null +++ b/app/src/main/java/com/umc/ttoklip/util/TtoklipFirebaseMessagingService.kt @@ -0,0 +1,166 @@ +package com.umc.ttoklip.util + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.media.RingtoneManager +import android.os.Build +import android.util.Log +import androidx.core.app.NotificationCompat +import com.google.firebase.messaging.FirebaseMessaging +import com.google.firebase.messaging.FirebaseMessagingService +import com.google.firebase.messaging.RemoteMessage +import com.umc.ttoklip.R +import com.umc.ttoklip.presentation.MainActivity +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.tasks.await +import kotlinx.coroutines.withContext +import java.net.URL + +@AndroidEntryPoint +class TtoklipFirebaseMessagingService : FirebaseMessagingService() { + + private val TAG = "FirebaseService" + + override fun onNewToken(token: String) { + Log.d(TAG, "new Token: $token") + } + + /** 메시지 수신 메서드(포그라운드) */ + override fun onMessageReceived(remoteMessage: RemoteMessage) { + Log.d(TAG, "From: " + remoteMessage.from) + Log.d(TAG, "Message data : ${remoteMessage.data}") + Log.d(TAG, "Message noti : ${remoteMessage.notification}") + + if (remoteMessage.data.isNotEmpty()){ + handleNotification(remoteMessage) + + }else{ + // 데이터 메시지 비어있음 + Log.d(TAG, "메시지를 수신하지 못했습니다.") + } + + } + + private fun handleNotification(remoteMessage: RemoteMessage) { + var channelName = "공지사항" + sendNotification(remoteMessage, "똑립알림", channelName) + } + + + private fun createMainActivityIntent( + data: Map, + ): Intent { + val intent = Intent(this, MainActivity::class.java) + data.forEach { (key, value) -> + intent.putExtra(key, value) + } + + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) + return intent + } + + private fun sendNotification(remoteMessage: RemoteMessage, channelId: String, channelName: String) { + CoroutineScope(Dispatchers.IO).launch { + val bigPicture: Bitmap? = try { + remoteMessage.data["imageUrl"]?.let { imageUrl -> + val url = URL(imageUrl) + BitmapFactory.decodeStream(url.openConnection().getInputStream()) + } + } catch (e: Exception) { + e.printStackTrace() + null + } + + withContext(Dispatchers.Main) { + val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val uniId: Int = (System.currentTimeMillis() / 7).toInt() + + val intent = createMainActivityIntent(remoteMessage.data) + val pendingIntent = PendingIntent.getActivity( + this@TtoklipFirebaseMessagingService, + uniId, + intent, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE + ) + + val notificationBuilder = NotificationCompat.Builder( + this@TtoklipFirebaseMessagingService, channelId + ).apply { + priority = NotificationCompat.PRIORITY_HIGH + setSmallIcon(R.drawable.ic_logo_24) + setContentTitle(remoteMessage.data["title"]) + setContentText(remoteMessage.data["text"]) + setAutoCancel(true) + setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) + setContentIntent(pendingIntent) + + bigPicture?.let { + setStyle(NotificationCompat.BigPictureStyle() + .bigPicture(it) + .bigLargeIcon(null as Bitmap?)) + + setLargeIcon(it) + } + } + + // Android 최신버전 대응 (Android O 이상) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channel = + NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT) + notificationManager.createNotificationChannel(channel) + } + + notificationManager.notify(uniId, notificationBuilder.build()) + + } + } + } + suspend fun getFirebaseToken(): String { + val tokenTask = withContext(CoroutineScope(Dispatchers.IO).coroutineContext) { + FirebaseMessaging.getInstance().token.addOnSuccessListener { + Log.d("FCM", "token=${it}") + } + } + return tokenTask.await() + } + + enum class FragmentDestination { + NEWS, + } + + enum class FcmTopic{ + COMMIT, + } + +} + +/** +"notificationBuilder" 알림 생성시 여러가지 옵션을 이용해 커스텀 가능. +setSmallIcon : 작은 아이콘 (필수) +setContentTitle : 제목 (필수) +setContentText : 내용 (필수) +setColor : 알림내 앱 이름 색 +setWhen : 받은 시간 커스텀 ( 기본 시스템에서 제공합니다 ) +setShowWhen : 알림 수신 시간 ( default 값은 true, false시 숨길 수 있습니다 ) +setOnlyAlertOnce : 알림 1회 수신 ( 동일 아이디의 알림을 처음 받았을때만 알린다, 상태바에 알림이 잔존하면 무음 ) +setContentTitle : 제목 +setContentText : 내용 +setFullScreenIntent : 긴급 알림 ( 자세한 설명은 아래에서 설명합니다 ) +setTimeoutAfter : 알림 자동 사라지기 ( 지정한 시간 후 수신된 알림이 사라집니다 ) +setContentIntent : 알림 클릭시 이벤트 ( 지정하지 않으면 클릭했을때 아무 반응이 없고 setAutoCancel 또한 작동하지 않는다 ) +setLargeIcon : 큰 아이콘 ( mipmap 에 있는 아이콘이 아닌 drawable 폴더에 있는 아이콘을 사용해야 합니다. ) +setAutoCancel : 알림 클릭시 삭제 여부 ( true = 클릭시 삭제 , false = 클릭시 미삭제 ) +setPriority : 알림의 중요도를 설정 ( 중요도에 따라 head up 알림으로 설정할 수 있는데 자세한 내용은 밑에서 설명하겠습니다. ) +setVisibility : 잠금 화면내 알림 노출 여부 +Notification.VISIBILITY_PRIVATE : 알림의 기본 정보만 노출 (제목, 타이틀 등등) +Notification.VISIBILITY_PUBLIC : 알림의 모든 정보 노출 +Notification.VISIBILITY_SECRET : 알림의 모든 정보 비노출 + */ \ No newline at end of file diff --git a/app/src/main/java/com/umc/ttoklip/util/WriteHoneyTipUtil.kt b/app/src/main/java/com/umc/ttoklip/util/WriteHoneyTipUtil.kt index 7d6b9026..3b65dc1b 100644 --- a/app/src/main/java/com/umc/ttoklip/util/WriteHoneyTipUtil.kt +++ b/app/src/main/java/com/umc/ttoklip/util/WriteHoneyTipUtil.kt @@ -18,9 +18,9 @@ class WriteHoneyTipUtil(private val context: Context) { val imageParts: MutableList = mutableListOf() if (images.isNotEmpty()) { for (i in images.indices) { - //Log.d("images", images[i].toString()) + Log.d("images", images[i].toString()) val imagePath = images[i] - val path = convertResizeImage(imagePath) + //val path = convertResizeImage(imagePath) Log.d("path", imagePath.lastPathSegment.toString()) val imageFile = convertUriToJpegFile(context, imagePath, imagePath.lastPathSegment.toString()) diff --git a/app/src/main/res/layout/activity_communication.xml b/app/src/main/res/layout/activity_communication.xml index f62c56be..c88529e2 100644 --- a/app/src/main/res/layout/activity_communication.xml +++ b/app/src/main/res/layout/activity_communication.xml @@ -7,7 +7,7 @@ + type="com.umc.ttoklip.presentation.hometown.communication.CommunicationViewModelImpl" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_other_honey_tip.xml b/app/src/main/res/layout/activity_other_honey_tip.xml new file mode 100644 index 00000000..550f7b3f --- /dev/null +++ b/app/src/main/res/layout/activity_other_honey_tip.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_otheruser_profile.xml b/app/src/main/res/layout/activity_otheruser_profile.xml index 4ce2cc48..74074743 100644 --- a/app/src/main/res/layout/activity_otheruser_profile.xml +++ b/app/src/main/res/layout/activity_otheruser_profile.xml @@ -1,428 +1,462 @@ - - - + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:bind="http://schemas.android.com/tools" + xmlns:tools="http://schemas.android.com/tools"> + + + + + - + + + + - + + + + + + + - + android:layout_marginTop="30dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/otherprofile_back_ib"> - + - - - + + + + + + + + + + + + + + + + + + + + + + - - - + app:layout_constraintTop_toBottomOf="@id/otherprofile_userinfo_cl"> - + + + + + + + + + + + + + + + + + + app:layout_constraintStart_toStartOf="@id/otherprofile_level_cl" + app:layout_constraintTop_toBottomOf="@id/otherprofile_level_cl" /> + - + android:text="님의 지난 기록" + android:textAppearance="@style/TextAppearance.App.14sp_700" + app:layout_constraintBottom_toBottomOf="@id/otherprofile_history_nick_tv" + app:layout_constraintStart_toEndOf="@id/otherprofile_history_nick_tv" + app:layout_constraintTop_toTopOf="@id/otherprofile_history_nick_tv" /> + + app:layout_constraintStart_toStartOf="@id/otherprofile_history_nick_tv" + app:layout_constraintTop_toBottomOf="@id/otherprofile_history_nick_tv"> - + app:layout_constraintEnd_toStartOf="@id/otherprofile_trade_tv" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/otherprofile_trade_iv" + app:layout_constraintTop_toTopOf="parent" /> - - - - - + - - + android:layout_height="40dp" + android:layout_marginStart="15dp" + android:background="@drawable/rectangle_corner_10" + android:backgroundTint="@color/yellow" + app:layout_constraintStart_toEndOf="@id/otherprofile_trade_cl" + app:layout_constraintTop_toTopOf="@id/otherprofile_trade_cl"> + + + + + + + android:layout_marginTop="20dp" + android:ellipsize="end" + android:lines="1" + android:maxWidth="150dp" + android:text="@{vm.strangerInfo.nickname}" + android:textAppearance="@style/TextAppearance.App.14sp_700" + app:layout_constraintStart_toStartOf="@id/otherprofile_trade_cl" + app:layout_constraintTop_toBottomOf="@id/otherprofile_trade_cl" /> + + android:text="님의 독립경력" + android:textAppearance="@style/TextAppearance.App.14sp_700" + app:layout_constraintBottom_toBottomOf="@id/otherprofile_independ_nick_tv" + app:layout_constraintStart_toEndOf="@id/otherprofile_independ_nick_tv" + app:layout_constraintTop_toTopOf="@id/otherprofile_independ_nick_tv" /> + - - - - - - - - - - - - + app:layout_constraintTop_toBottomOf="@id/otherprofile_independ_nick_tv" /> - + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + - - + + + + + + + - - - - - - + + + + + + + + - - - + + + + + + + + - + + + + + + + + + + - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_read_communication.xml b/app/src/main/res/layout/activity_read_communication.xml index 8599bbc0..77f891ce 100644 --- a/app/src/main/res/layout/activity_read_communication.xml +++ b/app/src/main/res/layout/activity_read_communication.xml @@ -7,7 +7,7 @@ + type="com.umc.ttoklip.presentation.hometown.communication.read.ReadCommunicationViewModel" /> @@ -289,7 +290,7 @@ android:layout_height="16dp" android:layout_margin="4dp" android:src="@drawable/ic_bookmark_off_20" - android:tint="@color/gray60" + android:tint="@{vm.scrap ? @color/black : @color/gray60}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -302,7 +303,7 @@ android:paddingEnd="6dp" android:text="스크랩" android:textAppearance="@style/TextAppearance.App.10sp_500" - android:textColor="@color/gray60" + android:textColor="@{vm.scrap ? @color/black : @color/gray60}" app:layout_constraintBottom_toBottomOf="@id/scrapBtnImg" app:layout_constraintStart_toEndOf="@id/scrapBtnImg" app:layout_constraintTop_toTopOf="@id/scrapBtnImg" /> @@ -316,7 +317,8 @@ android:layout_marginStart="12dp" android:layout_marginTop="12dp" android:background="@drawable/rectangle_corner_4" - android:backgroundTint="@color/gray20" + android:backgroundTint="@{vm.like ? @color/yellow : @color/gray20}" + android:onClick="@{()->vm.changeLike()}" app:layout_constraintStart_toEndOf="@id/scrapBtn" app:layout_constraintTop_toBottomOf="@id/bookmarkImg"> @@ -326,7 +328,7 @@ android:layout_height="16dp" android:layout_margin="4dp" android:src="@drawable/ic_heart_off_20" - android:tint="@color/gray60" + android:tint="@{vm.like ? @color/black : @color/gray60}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -339,7 +341,7 @@ android:paddingEnd="6dp" android:text="좋아요" android:textAppearance="@style/TextAppearance.App.10sp_500" - android:textColor="@color/gray60" + android:textColor="@{vm.like ? @color/black : @color/gray60}" app:layout_constraintBottom_toBottomOf="@id/likeBtnImg" app:layout_constraintStart_toEndOf="@id/likeBtnImg" app:layout_constraintTop_toTopOf="@id/likeBtnImg" /> @@ -389,6 +391,13 @@ + + + - diff --git a/app/src/main/res/layout/activity_read_together.xml b/app/src/main/res/layout/activity_read_together.xml index 07fda3a2..dee49ae2 100644 --- a/app/src/main/res/layout/activity_read_together.xml +++ b/app/src/main/res/layout/activity_read_together.xml @@ -1,13 +1,14 @@ + xmlns:tools="http://schemas.android.com/tools" + xmlns:bind="http://schemas.android.com/apk/res-auto"> + type="com.umc.ttoklip.presentation.hometown.together.read.ReadTogetherViewModel" /> @@ -39,60 +40,23 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/backBtn" /> - - - - - - - - - - - - - - - - - + tools:visibility="visible" /> + tools:visibility="gone" /> @@ -350,28 +314,31 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@{vm.joinState ? @drawable/yellow_btn_background : @drawable/rectangle_corner_10_strok_1_gray40}" - android:onClick="@{()->vm.joinBtnClick()}" android:paddingHorizontal="15dp" android:paddingVertical="7dp" android:text="@{vm.joinState ? @string/join_together : @string/cancel_join}" android:textAppearance="@style/TextAppearance.App.12sp_700" android:textColor="@color/black" - android:visibility="@{vm.deadlineState ? View.GONE : View.VISIBLE}" + bind:isDeadLine="@{vm.deadlineState}" + bind:joinVisible="@{vm.joinState}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> + @@ -379,7 +346,6 @@ android:id="@+id/owner_join_frame" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:visibility="@{vm.isOwner ? View.VISIBLE : View.GONE}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent"> @@ -391,9 +357,11 @@ android:paddingHorizontal="15dp" android:paddingVertical="7dp" android:text="@string/set_deadline" + bind:isWriter="@{vm.isWriter}" + bind:isDeadLine="@{vm.deadlineState}" android:textAppearance="@style/TextAppearance.App.12sp_700" android:textColor="@color/orange" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@id/deadline_end_tv" app:layout_constraintTop_toTopOf="parent" /> + + @@ -447,20 +429,25 @@ android:layout_height="wrap_content" android:layout_marginTop="12dp" android:layout_marginBottom="100dp" - android:layout_marginHorizontal="24dp" android:nestedScrollingEnabled="false" android:overScrollMode="never" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="@id/image_line" + app:layout_constraintStart_toStartOf="@id/image_line" app:layout_constraintTop_toBottomOf="@id/current_member_stat_frame" tools:listitem="@layout/item_comment" /> - + + app:layout_constraintStart_toStartOf="parent"> + + - diff --git a/app/src/main/res/layout/activity_signup.xml b/app/src/main/res/layout/activity_signup.xml index dde7e177..a8339f8a 100644 --- a/app/src/main/res/layout/activity_signup.xml +++ b/app/src/main/res/layout/activity_signup.xml @@ -40,7 +40,7 @@ android:layout_height="0dp" android:layout_marginTop="15dp" android:background="@null" - android:max="3" + android:max="5" android:paddingStart="0dp" android:paddingEnd="0dp" android:progress="1" diff --git a/app/src/main/res/layout/activity_together.xml b/app/src/main/res/layout/activity_together.xml index c6da0f4a..b55e804e 100644 --- a/app/src/main/res/layout/activity_together.xml +++ b/app/src/main/res/layout/activity_together.xml @@ -7,7 +7,7 @@ + type="com.umc.ttoklip.presentation.hometown.together.TogetherViewModel" /> + type="com.umc.ttoklip.presentation.hometown.communication.write.WriteCommunicationViewModelImpl" /> diff --git a/app/src/main/res/layout/activity_write_honey_tip.xml b/app/src/main/res/layout/activity_write_honey_tip.xml index 8b9ff0de..95d6c195 100644 --- a/app/src/main/res/layout/activity_write_honey_tip.xml +++ b/app/src/main/res/layout/activity_write_honey_tip.xml @@ -4,6 +4,8 @@ xmlns:tools="http://schemas.android.com/tools"> + + @@ -40,7 +42,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="24dp" - android:text="작성완료" + android:text='@{viewModel.isEdit ? "수정완료":"작성완료"}' + android:enabled="@{viewModel.isWriteDoneBtnEnable}" android:textAppearance="@style/TextAppearance.App.12sp_400" android:textColor="@color/write_btn_selector" app:layout_constraintBottom_toBottomOf="@id/title_tv" @@ -72,7 +75,7 @@ app:tabGravity="fill" app:tabIndicatorColor="@color/white" app:tabIndicatorHeight="0dp" - app:tabMode="fixed" + app:tabMode="scrollable" app:tabPaddingBottom="10dp" app:tabPaddingTop="10dp" app:tabRippleColor="@null" diff --git a/app/src/main/res/layout/activity_write_together.xml b/app/src/main/res/layout/activity_write_together.xml index ed995d9a..ce23a922 100644 --- a/app/src/main/res/layout/activity_write_together.xml +++ b/app/src/main/res/layout/activity_write_together.xml @@ -7,7 +7,7 @@ + type="com.umc.ttoklip.presentation.hometown.together.write.WriteTogetherViewModelImpl" /> diff --git a/app/src/main/res/layout/dialog_cart_finish.xml b/app/src/main/res/layout/dialog_cart_finish.xml new file mode 100644 index 00000000..0cc7cd54 --- /dev/null +++ b/app/src/main/res/layout/dialog_cart_finish.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_write_together.xml b/app/src/main/res/layout/dialog_write_together.xml index a45d388e..a8b42967 100644 --- a/app/src/main/res/layout/dialog_write_together.xml +++ b/app/src/main/res/layout/dialog_write_together.xml @@ -16,7 +16,7 @@ android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginHorizontal="16dp" + android:layout_marginHorizontal="52dp" android:layout_marginTop="28dp" android:text="함께하기에 참여하시겠어요?" android:textAppearance="@style/TextAppearance.App.14sp_600" diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index ab6c7647..3bf228f9 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -53,48 +53,6 @@ app:layout_constraintTop_toTopOf="parent" /> - - - - - - - - + + + + + + + + + + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.0" /> + @@ -51,37 +53,11 @@ android:layout_height="wrap_content" android:layout_marginStart="12dp" android:layout_marginTop="4dp" - android:text="글을 누군가 댓글을 달았어요" + android:text="@{item.text}" android:textAppearance="@style/TextAppearance.App.10sp_400" app:layout_constraintStart_toEndOf="@id/cardV" app:layout_constraintTop_toBottomOf="@id/titleT" /> - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/item_announcement_content.xml b/app/src/main/res/layout/item_announcement_content.xml index 88ca0a61..0efde72a 100644 --- a/app/src/main/res/layout/item_announcement_content.xml +++ b/app/src/main/res/layout/item_announcement_content.xml @@ -20,17 +20,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - + \ No newline at end of file diff --git a/app/src/main/res/layout/item_announcement_content_detail.xml b/app/src/main/res/layout/item_announcement_content_detail.xml deleted file mode 100644 index 7baf32a1..00000000 --- a/app/src/main/res/layout/item_announcement_content_detail.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/item_announcements.xml b/app/src/main/res/layout/item_announcements.xml index fbd8e0ff..76894061 100644 --- a/app/src/main/res/layout/item_announcements.xml +++ b/app/src/main/res/layout/item_announcements.xml @@ -41,26 +41,27 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@id/announcement_title_tv" /> - + - - - - - + android:text="약관 내용\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n내용내용\n\n\n\n\n냠냠" + android:textAppearance="@style/TextAppearance.App.12sp_400" + android:padding="10dp"/> + \ No newline at end of file diff --git a/app/src/main/res/layout/item_comment.xml b/app/src/main/res/layout/item_comment.xml index c9ce7d9a..181dbe1a 100644 --- a/app/src/main/res/layout/item_comment.xml +++ b/app/src/main/res/layout/item_comment.xml @@ -25,6 +25,7 @@ app:layout_constraintTop_toTopOf="parent"> diff --git a/app/src/main/res/layout/item_reply.xml b/app/src/main/res/layout/item_reply.xml index 3d92ddf5..d0503df0 100644 --- a/app/src/main/res/layout/item_reply.xml +++ b/app/src/main/res/layout/item_reply.xml @@ -43,6 +43,7 @@ app:layout_constraintTop_toTopOf="parent"> diff --git a/app/src/main/res/layout/item_transaction_history.xml b/app/src/main/res/layout/item_transaction_history.xml index 0fc747cf..122f0913 100644 --- a/app/src/main/res/layout/item_transaction_history.xml +++ b/app/src/main/res/layout/item_transaction_history.xml @@ -78,6 +78,7 @@ android:layout_width="wrap_content" android:layout_height="24dp" android:text="마감" + android:textColor="@color/orange" android:textAppearance="@style/TextAppearance.App.10sp_400" app:chipBackgroundColor="@color/gray20" app:chipCornerRadius="100dp" diff --git a/app/src/main/res/navigation/signup_graph.xml b/app/src/main/res/navigation/signup_graph.xml index fe8c08e2..a0c0e7cf 100644 --- a/app/src/main/res/navigation/signup_graph.xml +++ b/app/src/main/res/navigation/signup_graph.xml @@ -3,7 +3,36 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/signup_graph" - app:startDestination="@id/signup3_fragment"> + app:startDestination="@id/signup1_fragment"> + + + + + + + + + + + app:enterAnim="@anim/nav_default_enter_anim" + app:popExitAnim="@anim/nav_default_exit_anim" /> + + app:destination="@id/signup3_fragment" + app:popUpTo="@id/signup3_fragment"/> - - - - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3431113..b7f66ab1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ - ttoklip + 똑립 diff --git a/build.gradle b/build.gradle index c9fd1b2e..c4094802 100644 --- a/build.gradle +++ b/build.gradle @@ -3,5 +3,6 @@ plugins { id 'com.android.application' version '8.0.0' apply false id 'com.android.library' version '8.0.0' apply false id 'org.jetbrains.kotlin.android' version '1.8.0' apply false + id 'com.google.gms.google-services' version "4.4.1" apply false id "com.google.dagger.hilt.android" version '2.47' apply false } \ No newline at end of file