From 85f6cd5677bf08c736670c49f6232dd40a70edd0 Mon Sep 17 00:00:00 2001 From: Haeseong Jeon Date: Sat, 10 Dec 2022 16:44:53 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20notification=20module=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 4 + .../src/main/res/drawable/ic_notibox.xml | 13 +++ .../navigator/NotificationNavigator.kt | 4 + presentation/home/build.gradle | 1 + .../home/src/main/AndroidManifest.xml | 2 +- .../threedays/home/home/HomeFragment.kt | 16 +++ .../src/main/res/layout/fragment_home.xml | 1 + presentation/notification/.gitignore | 1 + presentation/notification/build.gradle | 52 +++++++++ presentation/notification/consumer-rules.pro | 0 presentation/notification/proguard-rules.pro | 21 ++++ .../notification/src/main/AndroidManifest.xml | 7 ++ .../notification/NotificationActivity.kt | 16 +++ .../notification/NotificationModule.kt | 15 +++ .../notification/NotificationNavigatorImpl.kt | 12 ++ .../notification/NotificationViewModel.kt | 11 ++ .../main/res/layout/activity_notification.xml | 104 ++++++++++++++++++ .../src/main/res/values/strings.xml | 7 ++ settings.gradle | 1 + 20 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 core-design-system/src/main/res/drawable/ic_notibox.xml create mode 100644 navigator/src/main/java/com/depromeet/threedays/navigator/NotificationNavigator.kt create mode 100644 presentation/notification/.gitignore create mode 100644 presentation/notification/build.gradle create mode 100644 presentation/notification/consumer-rules.pro create mode 100644 presentation/notification/proguard-rules.pro create mode 100644 presentation/notification/src/main/AndroidManifest.xml create mode 100644 presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt create mode 100644 presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationModule.kt create mode 100644 presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationNavigatorImpl.kt create mode 100644 presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewModel.kt create mode 100644 presentation/notification/src/main/res/layout/activity_notification.xml create mode 100644 presentation/notification/src/main/res/values/strings.xml diff --git a/app/build.gradle b/app/build.gradle index af13dfb6..cd3e28bd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -45,6 +45,7 @@ dependencies { implementation(project(":navigator")) implementation(project(":presentation:home")) implementation(project(":presentation:create")) + implementation(project(":presentation:notification")) implementation(jetpackDeps) implementation(coroutines) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c05fb080..03495932 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -34,6 +34,10 @@ + + diff --git a/core-design-system/src/main/res/drawable/ic_notibox.xml b/core-design-system/src/main/res/drawable/ic_notibox.xml new file mode 100644 index 00000000..c5ae0bad --- /dev/null +++ b/core-design-system/src/main/res/drawable/ic_notibox.xml @@ -0,0 +1,13 @@ + + + diff --git a/navigator/src/main/java/com/depromeet/threedays/navigator/NotificationNavigator.kt b/navigator/src/main/java/com/depromeet/threedays/navigator/NotificationNavigator.kt new file mode 100644 index 00000000..499de2ad --- /dev/null +++ b/navigator/src/main/java/com/depromeet/threedays/navigator/NotificationNavigator.kt @@ -0,0 +1,4 @@ +package com.depromeet.threedays.navigator + +interface NotificationNavigator : Navigator { +} diff --git a/presentation/home/build.gradle b/presentation/home/build.gradle index 2322b116..b21a1615 100644 --- a/presentation/home/build.gradle +++ b/presentation/home/build.gradle @@ -48,6 +48,7 @@ dependencies { implementation(project(":presentation:history")) implementation(project(":presentation:mate")) implementation(project(":presentation:mypage")) + implementation(project(":presentation:notification")) implementation(jetpackDeps) implementation(coroutines) diff --git a/presentation/home/src/main/AndroidManifest.xml b/presentation/home/src/main/AndroidManifest.xml index f1797983..ce6090fa 100644 --- a/presentation/home/src/main/AndroidManifest.xml +++ b/presentation/home/src/main/AndroidManifest.xml @@ -1,3 +1,3 @@ \ No newline at end of file + package="com.depromeet.threedays.home"/> diff --git a/presentation/home/src/main/java/com/depromeet/threedays/home/home/HomeFragment.kt b/presentation/home/src/main/java/com/depromeet/threedays/home/home/HomeFragment.kt index 86c7cf5a..9a5bcb58 100644 --- a/presentation/home/src/main/java/com/depromeet/threedays/home/home/HomeFragment.kt +++ b/presentation/home/src/main/java/com/depromeet/threedays/home/home/HomeFragment.kt @@ -17,6 +17,7 @@ import com.depromeet.threedays.home.R import com.depromeet.threedays.home.databinding.FragmentHomeBinding import com.depromeet.threedays.navigator.GoalAddNavigator import com.depromeet.threedays.navigator.GoalUpdateNavigator +import com.depromeet.threedays.navigator.NotificationNavigator import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import java.time.ZoneId @@ -34,6 +35,9 @@ class HomeFragment : BaseFragment(R.layout.f @Inject lateinit var goalUpdateNavigator: GoalUpdateNavigator + @Inject + lateinit var notificationNavigator: NotificationNavigator + private val addResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> when(result.resultCode) { @@ -55,6 +59,7 @@ class HomeFragment : BaseFragment(R.layout.f viewModel.fetchGoals() viewModel.setObserve() initView() + initEvent() } private fun onGoalClick(habitId: Int) { @@ -83,6 +88,11 @@ class HomeFragment : BaseFragment(R.layout.f dialog.show() } + private fun onNotificationClick() { + val intent = notificationNavigator.intent(requireContext()) + addResultLauncher.launch(intent) + } + private fun onDeleteConfirmClick(habitId: Int) { // viewModel.deleteGoals(habit.goalId) // viewModel.fetchGoals() @@ -117,6 +127,12 @@ class HomeFragment : BaseFragment(R.layout.f binding.tvDate.text = String.format("%02d월%02d일 %s요일", now.monthValue, now.dayOfMonth, dayOfWeekList[now.dayOfWeek.value - 1]) } + private fun initEvent() { + binding.ivNotification.setOnClickListener { + onNotificationClick() + } + } + private fun HomeViewModel.setObserve() { lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { diff --git a/presentation/home/src/main/res/layout/fragment_home.xml b/presentation/home/src/main/res/layout/fragment_home.xml index 83357607..233eaea0 100644 --- a/presentation/home/src/main/res/layout/fragment_home.xml +++ b/presentation/home/src/main/res/layout/fragment_home.xml @@ -38,6 +38,7 @@ tools:text="10월19일 목요일" /> + + + + + diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt new file mode 100644 index 00000000..7c8eaf34 --- /dev/null +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt @@ -0,0 +1,16 @@ +package com.depromeet.threedays.notification + +import android.os.Bundle +import androidx.activity.viewModels +import com.depromeet.threedays.core.BaseActivity +import com.depromeet.threedays.notification.databinding.ActivityNotificationBinding +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class NotificationActivity : BaseActivity(R.layout.activity_notification) { + private val viewModel by viewModels() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } +} diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationModule.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationModule.kt new file mode 100644 index 00000000..6fae66b0 --- /dev/null +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationModule.kt @@ -0,0 +1,15 @@ +package com.depromeet.threedays.notification + +import com.depromeet.threedays.navigator.NotificationNavigator +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent + +@Module +@InstallIn(SingletonComponent::class) +internal abstract class NotificationModule { + + @Binds + abstract fun bindNotificationNavigator(navi: NotificationNavigatorImpl): NotificationNavigator +} diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationNavigatorImpl.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationNavigatorImpl.kt new file mode 100644 index 00000000..c7342a91 --- /dev/null +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationNavigatorImpl.kt @@ -0,0 +1,12 @@ +package com.depromeet.threedays.notification + +import android.content.Context +import android.content.Intent +import com.depromeet.threedays.navigator.NotificationNavigator +import javax.inject.Inject + +class NotificationNavigatorImpl @Inject constructor(): NotificationNavigator { + override fun intent(context: Context): Intent { + return Intent(context, NotificationActivity::class.java) + } +} diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewModel.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewModel.kt new file mode 100644 index 00000000..b66070dd --- /dev/null +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewModel.kt @@ -0,0 +1,11 @@ +package com.depromeet.threedays.notification + +import com.depromeet.threedays.core.BaseViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class NotificationViewModel @Inject constructor( +) : BaseViewModel() { + +} diff --git a/presentation/notification/src/main/res/layout/activity_notification.xml b/presentation/notification/src/main/res/layout/activity_notification.xml new file mode 100644 index 00000000..b3315013 --- /dev/null +++ b/presentation/notification/src/main/res/layout/activity_notification.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/presentation/notification/src/main/res/values/strings.xml b/presentation/notification/src/main/res/values/strings.xml new file mode 100644 index 00000000..d368a61b --- /dev/null +++ b/presentation/notification/src/main/res/values/strings.xml @@ -0,0 +1,7 @@ + + 알림 + 아직 새로운 알림이 없어요. + (알림은 30일 후 자동 삭제됩니다.) + 뒤로 버튼 + 알림 아이콘 + diff --git a/settings.gradle b/settings.gradle index 8ed562a3..3533bcdf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -25,3 +25,4 @@ include ':presentation:create' include ':presentation:history' include ':presentation:mypage' include ':presentation:mate' +include ':presentation:notification' From ae7138b54eb59410a9399bc18a367f068ec9c8f0 Mon Sep 17 00:00:00 2001 From: juhwankim-dev Date: Sat, 10 Dec 2022 17:06:12 +0900 Subject: [PATCH 2/8] =?UTF-8?q?ui:=20=EC=95=8C=EB=A6=BC=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20=EC=95=88=EB=82=B4=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/layout/activity_notification.xml | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/presentation/notification/src/main/res/layout/activity_notification.xml b/presentation/notification/src/main/res/layout/activity_notification.xml index b3315013..61841454 100644 --- a/presentation/notification/src/main/res/layout/activity_notification.xml +++ b/presentation/notification/src/main/res/layout/activity_notification.xml @@ -28,41 +28,45 @@ android:id="@+id/iv_back" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginStart="20dp" android:contentDescription="@string/description_btn_back" android:gravity="center_vertical" android:src="@drawable/ic_arrow_out" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + app:layout_constraintTop_toTopOf="@+id/iv_back" /> + app:layout_constraintTop_toBottomOf="@id/container_header" + app:layout_constraintBottom_toBottomOf="parent"> + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"> From 7612f21c37933df9ff6bd2290dfa93390f245ba9 Mon Sep 17 00:00:00 2001 From: juhwankim-dev Date: Sat, 10 Dec 2022 17:16:15 +0900 Subject: [PATCH 3/8] =?UTF-8?q?ui:=20=EC=95=8C=EB=A6=BC=20item=20ui=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/drawable/bg_rect_gray600_r10.xml | 8 ++++ .../src/main/res/layout/item_notification.xml | 45 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 core-design-system/src/main/res/drawable/bg_rect_gray600_r10.xml create mode 100644 presentation/notification/src/main/res/layout/item_notification.xml diff --git a/core-design-system/src/main/res/drawable/bg_rect_gray600_r10.xml b/core-design-system/src/main/res/drawable/bg_rect_gray600_r10.xml new file mode 100644 index 00000000..fcc8391e --- /dev/null +++ b/core-design-system/src/main/res/drawable/bg_rect_gray600_r10.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/presentation/notification/src/main/res/layout/item_notification.xml b/presentation/notification/src/main/res/layout/item_notification.xml new file mode 100644 index 00000000..7dbae599 --- /dev/null +++ b/presentation/notification/src/main/res/layout/item_notification.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + From 0fb4786fdee0dd389dc4ab100def5c3002fa68a5 Mon Sep 17 00:00:00 2001 From: Haeseong Jeon Date: Sat, 10 Dec 2022 17:37:55 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20notification=20item=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/layout/item_notification.xml | 48 ++++++++++++++----- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/presentation/notification/src/main/res/layout/item_notification.xml b/presentation/notification/src/main/res/layout/item_notification.xml index 7dbae599..350dccd6 100644 --- a/presentation/notification/src/main/res/layout/item_notification.xml +++ b/presentation/notification/src/main/res/layout/item_notification.xml @@ -1,45 +1,67 @@ + android:layout_height="wrap_content" + android:background="@color/gray_100"> + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintStart_toEndOf="@id/iv_logo" + app:layout_constraintTop_toTopOf="@id/iv_logo" /> + app:layout_constraintEnd_toEndOf="@id/gl_notification_content" + app:layout_constraintStart_toStartOf="@id/tv_notification_title" + app:layout_constraintTop_toBottomOf="@id/tv_notification_title" /> + + + app:layout_constraintStart_toStartOf="@id/tv_notification_title" + app:layout_constraintTop_toBottomOf="@id/tv_notification_content" /> + + From 17ba35dec7f235c015d262318d9172c110c9e12d Mon Sep 17 00:00:00 2001 From: juhwankim-dev Date: Sat, 10 Dec 2022 18:00:49 +0900 Subject: [PATCH 5/8] =?UTF-8?q?ui:=20=EC=95=8C=EB=A6=BC=20item=EC=9D=84=20?= =?UTF-8?q?databinding=20layout=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/layout/item_notification.xml | 125 +++++++++--------- 1 file changed, 66 insertions(+), 59 deletions(-) diff --git a/presentation/notification/src/main/res/layout/item_notification.xml b/presentation/notification/src/main/res/layout/item_notification.xml index 350dccd6..5e153278 100644 --- a/presentation/notification/src/main/res/layout/item_notification.xml +++ b/presentation/notification/src/main/res/layout/item_notification.xml @@ -1,67 +1,74 @@ - + - + - + - + android:background="@color/gray_100"> - + - + + + + + + + - - + + + From e6f6e6ca3171b98a564bfc775dde3b33d9834185 Mon Sep 17 00:00:00 2001 From: juhwankim-dev Date: Sat, 10 Dec 2022 18:01:54 +0900 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20=EC=95=8C=EB=A6=BC=20adapter,=20mod?= =?UTF-8?q?el,=20viewHolder=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/NotificationAdapter.kt | 34 +++++++++++++++++++ .../threedays/notification/NotificationUI.kt | 7 ++++ .../notification/NotificationViewHolder.kt | 25 ++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationAdapter.kt create mode 100644 presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationUI.kt create mode 100644 presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewHolder.kt diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationAdapter.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationAdapter.kt new file mode 100644 index 00000000..6f2b61a6 --- /dev/null +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationAdapter.kt @@ -0,0 +1,34 @@ +package com.depromeet.threedays.notification + +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter + +class NotificationAdapter : ListAdapter(DIFF_UTIL) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotificationViewHolder { + return NotificationViewHolder.create(parent, false) + } + + override fun onBindViewHolder(holder: NotificationViewHolder, position: Int) { + holder.onBind(getItem(position)) + } + + override fun getItemCount(): Int = currentList.size + + override fun getItemId(position: Int): Long { + return getItem(position).id + } + + companion object { + private val DIFF_UTIL = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: NotificationUI, newItem: NotificationUI): Boolean { + return oldItem.id == newItem.id + } + + override fun areContentsTheSame(oldItem: NotificationUI, newItem: NotificationUI): Boolean { + return oldItem == newItem + } + } + } +} diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationUI.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationUI.kt new file mode 100644 index 00000000..dd455d8f --- /dev/null +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationUI.kt @@ -0,0 +1,7 @@ +package com.depromeet.threedays.notification + +data class NotificationUI( + val id: Long, + val title: String, + val content: String +) diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewHolder.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewHolder.kt new file mode 100644 index 00000000..3d03b49a --- /dev/null +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewHolder.kt @@ -0,0 +1,25 @@ +package com.depromeet.threedays.notification + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.depromeet.threedays.notification.databinding.ItemNotificationBinding + +class NotificationViewHolder(private val binding: ItemNotificationBinding) : RecyclerView.ViewHolder(binding.root) { + fun onBind(notificationUI: NotificationUI) { + // 데이터 연결해주는 작업 + // binding.tvNotificationContent.text = notificationUI.title + } + + companion object { + fun create(parent: ViewGroup, attachToParent: Boolean): NotificationViewHolder { + return NotificationViewHolder( + ItemNotificationBinding.inflate( + LayoutInflater.from(parent.context), + parent, + attachToParent + ) + ) + } + } +} From 4cc618f88716599033cd327087c6dbd49edb40a0 Mon Sep 17 00:00:00 2001 From: Haeseong Jeon Date: Sat, 10 Dec 2022 19:37:59 +0900 Subject: [PATCH 7/8] =?UTF-8?q?feat:=20recycler=20view=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NotificationRemoteDataSource.kt | 9 +++++ .../NotificationRemoteDataSourceImpl.kt | 14 +++++++ .../threedays/data/di/RemoteModule.kt | 8 ++++ .../threedays/data/di/RepositoryModule.kt | 8 ++++ .../entity/notification/NotificationEntity.kt | 11 ++++++ .../data/mapper/NotificationMapper.kt | 10 +++++ .../repository/NotificationRepositoryImpl.kt | 31 +++++++++++++++ .../entity/notification/Notification.kt | 6 +-- .../repository/NotificationRepository.kt | 9 +++++ .../domain/usecase/GetNotificationsUseCase.kt | 15 +++++++ .../notification/NotificationActivity.kt | 39 +++++++++++++++++++ .../threedays/notification/NotificationUI.kt | 12 +++++- .../notification/NotificationViewHolder.kt | 6 ++- .../notification/NotificationViewModel.kt | 26 +++++++++++++ .../src/main/res/drawable/item_delimiter.xml | 10 +++++ .../main/res/layout/activity_notification.xml | 11 ++++++ 16 files changed, 220 insertions(+), 5 deletions(-) create mode 100644 data/src/main/java/com/depromeet/threedays/data/datasource/notification/NotificationRemoteDataSource.kt create mode 100644 data/src/main/java/com/depromeet/threedays/data/datasource/notification/NotificationRemoteDataSourceImpl.kt create mode 100644 data/src/main/java/com/depromeet/threedays/data/entity/notification/NotificationEntity.kt create mode 100644 data/src/main/java/com/depromeet/threedays/data/mapper/NotificationMapper.kt create mode 100644 data/src/main/java/com/depromeet/threedays/data/repository/NotificationRepositoryImpl.kt create mode 100644 domain/src/main/java/com/depromeet/threedays/domain/repository/NotificationRepository.kt create mode 100644 domain/src/main/java/com/depromeet/threedays/domain/usecase/GetNotificationsUseCase.kt create mode 100644 presentation/notification/src/main/res/drawable/item_delimiter.xml diff --git a/data/src/main/java/com/depromeet/threedays/data/datasource/notification/NotificationRemoteDataSource.kt b/data/src/main/java/com/depromeet/threedays/data/datasource/notification/NotificationRemoteDataSource.kt new file mode 100644 index 00000000..3fa31d29 --- /dev/null +++ b/data/src/main/java/com/depromeet/threedays/data/datasource/notification/NotificationRemoteDataSource.kt @@ -0,0 +1,9 @@ +package com.depromeet.threedays.data.datasource.notification + +import com.depromeet.threedays.data.entity.HabitEntity +import com.depromeet.threedays.data.entity.notification.NotificationEntity + +interface NotificationRemoteDataSource { + suspend fun setNotificationAsRead(notificationEntity: NotificationEntity) + suspend fun getNotifications(): List +} diff --git a/data/src/main/java/com/depromeet/threedays/data/datasource/notification/NotificationRemoteDataSourceImpl.kt b/data/src/main/java/com/depromeet/threedays/data/datasource/notification/NotificationRemoteDataSourceImpl.kt new file mode 100644 index 00000000..32cf4088 --- /dev/null +++ b/data/src/main/java/com/depromeet/threedays/data/datasource/notification/NotificationRemoteDataSourceImpl.kt @@ -0,0 +1,14 @@ +package com.depromeet.threedays.data.datasource.notification + +import com.depromeet.threedays.data.entity.notification.NotificationEntity +import javax.inject.Inject + +class NotificationRemoteDataSourceImpl @Inject constructor() : NotificationRemoteDataSource { + override suspend fun setNotificationAsRead(notificationEntity: NotificationEntity) { + TODO("Not yet implemented") + } + + override suspend fun getNotifications(): List { + return emptyList() + } +} diff --git a/data/src/main/java/com/depromeet/threedays/data/di/RemoteModule.kt b/data/src/main/java/com/depromeet/threedays/data/di/RemoteModule.kt index 0ded1f68..1feeeb14 100644 --- a/data/src/main/java/com/depromeet/threedays/data/di/RemoteModule.kt +++ b/data/src/main/java/com/depromeet/threedays/data/di/RemoteModule.kt @@ -2,6 +2,8 @@ package com.depromeet.threedays.data.di import com.depromeet.threedays.data.datasource.habit.HabitRemoteDataSource import com.depromeet.threedays.data.datasource.habit.HabitRemoteDataSourceImpl +import com.depromeet.threedays.data.datasource.notification.NotificationRemoteDataSource +import com.depromeet.threedays.data.datasource.notification.NotificationRemoteDataSourceImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -17,4 +19,10 @@ internal abstract class RemoteModule { abstract fun bindHabitRemoteDataSource( dataSource: HabitRemoteDataSourceImpl ): HabitRemoteDataSource + + @Binds + @Singleton + abstract fun bindNotificationRemoteDataSource( + dataSource: NotificationRemoteDataSourceImpl + ): NotificationRemoteDataSource } diff --git a/data/src/main/java/com/depromeet/threedays/data/di/RepositoryModule.kt b/data/src/main/java/com/depromeet/threedays/data/di/RepositoryModule.kt index 7663b398..4cf8d3ef 100644 --- a/data/src/main/java/com/depromeet/threedays/data/di/RepositoryModule.kt +++ b/data/src/main/java/com/depromeet/threedays/data/di/RepositoryModule.kt @@ -1,7 +1,9 @@ package com.depromeet.threedays.data.di import com.depromeet.threedays.data.repository.HabitRepositoryImpl +import com.depromeet.threedays.data.repository.NotificationRepositoryImpl import com.depromeet.threedays.domain.repository.HabitRepository +import com.depromeet.threedays.domain.repository.NotificationRepository import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -17,4 +19,10 @@ abstract class RepositoryModule { abstract fun bindsHabitRepository( repository: HabitRepositoryImpl ): HabitRepository + + @Binds + @Singleton + abstract fun bindsNotificationRepository( + repository: NotificationRepositoryImpl + ): NotificationRepository } diff --git a/data/src/main/java/com/depromeet/threedays/data/entity/notification/NotificationEntity.kt b/data/src/main/java/com/depromeet/threedays/data/entity/notification/NotificationEntity.kt new file mode 100644 index 00000000..96a0ff48 --- /dev/null +++ b/data/src/main/java/com/depromeet/threedays/data/entity/notification/NotificationEntity.kt @@ -0,0 +1,11 @@ +package com.depromeet.threedays.data.entity.notification + +/** + * 서버 응답에 맞추기 + */ +data class NotificationEntity( + val notificationId: Long, + val title: String, + val content: String, + val isRead: Boolean, +) diff --git a/data/src/main/java/com/depromeet/threedays/data/mapper/NotificationMapper.kt b/data/src/main/java/com/depromeet/threedays/data/mapper/NotificationMapper.kt new file mode 100644 index 00000000..6cfe0c51 --- /dev/null +++ b/data/src/main/java/com/depromeet/threedays/data/mapper/NotificationMapper.kt @@ -0,0 +1,10 @@ +package com.depromeet.threedays.data.mapper + +import com.depromeet.threedays.data.entity.notification.NotificationEntity +import com.depromeet.threedays.domain.entity.notification.Notification + +fun NotificationEntity.toNotification() = Notification( + this.notificationId, + this.title, + this.content, +) diff --git a/data/src/main/java/com/depromeet/threedays/data/repository/NotificationRepositoryImpl.kt b/data/src/main/java/com/depromeet/threedays/data/repository/NotificationRepositoryImpl.kt new file mode 100644 index 00000000..1a09432c --- /dev/null +++ b/data/src/main/java/com/depromeet/threedays/data/repository/NotificationRepositoryImpl.kt @@ -0,0 +1,31 @@ +package com.depromeet.threedays.data.repository + +import com.depromeet.threedays.domain.entity.DataState +import com.depromeet.threedays.domain.entity.notification.Notification +import com.depromeet.threedays.domain.repository.NotificationRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import javax.inject.Inject + +class NotificationRepositoryImpl @Inject constructor(): NotificationRepository { + override suspend fun getNotifications(): Flow>> { + // TODO: api 한테 목록 받아와서 + // mapper 한테 넘기고 + // 리턴 + return flow { + emit( + DataState.success( + listOf( + 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, + ).map { + Notification( + it, + "짝심삼일 소식", + "기다리고 기다리던 짝심삼일 ver.2가 출시되었습니다. 업데이트해보세요!", + ) + } + ) + ) + } + } +} diff --git a/domain/src/main/java/com/depromeet/threedays/domain/entity/notification/Notification.kt b/domain/src/main/java/com/depromeet/threedays/domain/entity/notification/Notification.kt index de077b02..a8ee6900 100644 --- a/domain/src/main/java/com/depromeet/threedays/domain/entity/notification/Notification.kt +++ b/domain/src/main/java/com/depromeet/threedays/domain/entity/notification/Notification.kt @@ -1,7 +1,7 @@ package com.depromeet.threedays.domain.entity.notification data class Notification ( - val notificationId: Int, - val notificationTime: String, - val contents: String, + val notificationId: Long, + val title: String, + val content: String, ) diff --git a/domain/src/main/java/com/depromeet/threedays/domain/repository/NotificationRepository.kt b/domain/src/main/java/com/depromeet/threedays/domain/repository/NotificationRepository.kt new file mode 100644 index 00000000..36b18b82 --- /dev/null +++ b/domain/src/main/java/com/depromeet/threedays/domain/repository/NotificationRepository.kt @@ -0,0 +1,9 @@ +package com.depromeet.threedays.domain.repository + +import com.depromeet.threedays.domain.entity.DataState +import com.depromeet.threedays.domain.entity.notification.Notification +import kotlinx.coroutines.flow.Flow + +interface NotificationRepository { + suspend fun getNotifications(): Flow>> +} diff --git a/domain/src/main/java/com/depromeet/threedays/domain/usecase/GetNotificationsUseCase.kt b/domain/src/main/java/com/depromeet/threedays/domain/usecase/GetNotificationsUseCase.kt new file mode 100644 index 00000000..c0e5b397 --- /dev/null +++ b/domain/src/main/java/com/depromeet/threedays/domain/usecase/GetNotificationsUseCase.kt @@ -0,0 +1,15 @@ +package com.depromeet.threedays.domain.usecase + +import com.depromeet.threedays.domain.entity.DataState +import com.depromeet.threedays.domain.entity.notification.Notification +import com.depromeet.threedays.domain.repository.NotificationRepository +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class GetNotificationsUseCase @Inject constructor( + private val notificationRepository: NotificationRepository, +) { + suspend operator fun invoke(): Flow>> { + return notificationRepository.getNotifications() + } +} diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt index 7c8eaf34..a16fbf58 100644 --- a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt @@ -1,16 +1,55 @@ package com.depromeet.threedays.notification +import android.graphics.Rect +import android.graphics.drawable.ColorDrawable import android.os.Bundle +import android.view.View import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import androidx.recyclerview.widget.DividerItemDecoration +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.depromeet.threedays.core.BaseActivity +import com.depromeet.threedays.core.util.dpToPx import com.depromeet.threedays.notification.databinding.ActivityNotificationBinding import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + @AndroidEntryPoint class NotificationActivity : BaseActivity(R.layout.activity_notification) { private val viewModel by viewModels() + lateinit var notificationAdapter: NotificationAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + notificationAdapter = NotificationAdapter() + binding.rvNotification.apply { + layoutManager = LinearLayoutManager(context) + adapter = notificationAdapter + + val dividerItemDecoration = DividerItemDecoration(context, LinearLayoutManager.VERTICAL) + dividerItemDecoration.setDrawable( + ColorDrawable(com.depromeet.threedays.core_design_system.R.color.light_blue_sub_color) +// context.resources.getDrawable(R.drawable.item_delimiter) + ) + addItemDecoration(dividerItemDecoration) + } + viewModel.fetchNotifications() + setObserve() + } + + private fun setObserve() { + lifecycleScope.launch { + lifecycle.repeatOnLifecycle(androidx.lifecycle.Lifecycle.State.STARTED) { + viewModel.apply { + notifications.collect { + notificationAdapter.submitList(it) + binding.containerNotificationEmpty.visibility = if (it.isEmpty()) View.VISIBLE else View.GONE + } + } + } + } } } diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationUI.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationUI.kt index dd455d8f..ed02c9a9 100644 --- a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationUI.kt +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationUI.kt @@ -1,7 +1,17 @@ package com.depromeet.threedays.notification +import com.depromeet.threedays.domain.entity.notification.Notification + data class NotificationUI( val id: Long, val title: String, val content: String -) +) { + companion object { + fun from(notification: Notification) = NotificationUI( + id = notification.notificationId, + title = notification.title, + content = notification.content + ) + } +} diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewHolder.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewHolder.kt index 3d03b49a..4ac1d91f 100644 --- a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewHolder.kt +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewHolder.kt @@ -4,11 +4,15 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.depromeet.threedays.notification.databinding.ItemNotificationBinding +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter class NotificationViewHolder(private val binding: ItemNotificationBinding) : RecyclerView.ViewHolder(binding.root) { fun onBind(notificationUI: NotificationUI) { // 데이터 연결해주는 작업 - // binding.tvNotificationContent.text = notificationUI.title + binding.tvNotificationTitle.text = notificationUI.title + binding.tvNotificationContent.text = notificationUI.content + binding.tvTime.text = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm")); } companion object { diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewModel.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewModel.kt index b66070dd..2e0dd6b5 100644 --- a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewModel.kt +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationViewModel.kt @@ -1,11 +1,37 @@ package com.depromeet.threedays.notification +import androidx.lifecycle.viewModelScope import com.depromeet.threedays.core.BaseViewModel +import com.depromeet.threedays.domain.entity.Status +import com.depromeet.threedays.domain.usecase.GetNotificationsUseCase 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 NotificationViewModel @Inject constructor( + private val getNotificationsUseCase: GetNotificationsUseCase, ) : BaseViewModel() { + private val _notifications: MutableStateFlow> = + MutableStateFlow(emptyList()) + val notifications: StateFlow> + get() = _notifications + + fun fetchNotifications() { + viewModelScope.launch { + getNotificationsUseCase().collect { response -> + when (response.status) { + Status.LOADING -> {} + Status.SUCCESS -> { + _notifications.value = response.data!!.map { NotificationUI.from(it) } + } + Status.ERROR -> {} + Status.FAIL -> {} + } + } + } + } } diff --git a/presentation/notification/src/main/res/drawable/item_delimiter.xml b/presentation/notification/src/main/res/drawable/item_delimiter.xml new file mode 100644 index 00000000..02d5c573 --- /dev/null +++ b/presentation/notification/src/main/res/drawable/item_delimiter.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/presentation/notification/src/main/res/layout/activity_notification.xml b/presentation/notification/src/main/res/layout/activity_notification.xml index 61841454..a9373f97 100644 --- a/presentation/notification/src/main/res/layout/activity_notification.xml +++ b/presentation/notification/src/main/res/layout/activity_notification.xml @@ -104,6 +104,17 @@ + + + From 6bb93ecaa20cd7df26a57debba1c79d4721ff5ce Mon Sep 17 00:00:00 2001 From: Haeseong Jeon Date: Sat, 10 Dec 2022 19:47:14 +0900 Subject: [PATCH 8/8] =?UTF-8?q?fix:=20divider=20=EC=95=88=EB=82=98?= =?UTF-8?q?=EC=98=A4=EB=8A=94=20=ED=98=84=EC=83=81=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../depromeet/threedays/notification/NotificationActivity.kt | 5 +---- .../notification/src/main/res/drawable/item_delimiter.xml | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt index a16fbf58..69a1a3d6 100644 --- a/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt +++ b/presentation/notification/src/main/java/com/depromeet/threedays/notification/NotificationActivity.kt @@ -30,10 +30,7 @@ class NotificationActivity : BaseActivity(R.layout. adapter = notificationAdapter val dividerItemDecoration = DividerItemDecoration(context, LinearLayoutManager.VERTICAL) - dividerItemDecoration.setDrawable( - ColorDrawable(com.depromeet.threedays.core_design_system.R.color.light_blue_sub_color) -// context.resources.getDrawable(R.drawable.item_delimiter) - ) + dividerItemDecoration.setDrawable(context.resources.getDrawable(R.drawable.item_delimiter)) addItemDecoration(dividerItemDecoration) } viewModel.fetchNotifications() diff --git a/presentation/notification/src/main/res/drawable/item_delimiter.xml b/presentation/notification/src/main/res/drawable/item_delimiter.xml index 02d5c573..53cdc474 100644 --- a/presentation/notification/src/main/res/drawable/item_delimiter.xml +++ b/presentation/notification/src/main/res/drawable/item_delimiter.xml @@ -5,6 +5,5 @@ - + -