From 4662a19cc4bd39ccc514c0ff4f8c5c9eb3c39615 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 13 Nov 2023 22:09:38 +0900 Subject: [PATCH 01/40] [add] gitignore google-services.json --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5888efe4..303541d3 100644 --- a/.gitignore +++ b/.gitignore @@ -120,7 +120,7 @@ captures/ *.pem # Google Services (e.g. APIs or Firebase) -# google-services.json +google-services.json # Android Patch gen-external-apklibs From 2b1738eeb06944a2ff7e39736a1239445bc5fedd Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 13 Nov 2023 22:10:18 +0900 Subject: [PATCH 02/40] [add] Dependencies, Plugins, Versions --- buildSrc/src/main/java/Dependencies.kt | 4 +++- buildSrc/src/main/java/Plugins.kt | 6 ++++++ buildSrc/src/main/java/Versions.kt | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index e0f1e1b2..abded618 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -26,6 +26,8 @@ object AndroidXDependencies { "androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.lifecycleVersion}" const val lifecycleJava8 = "androidx.lifecycle:lifecycle-common-java8:${Versions.lifecycleVersion}" + const val ossLicense = + "com.google.android.gms:play-services-oss-licenses:${Versions.ossVersion}" const val splashScreen = "androidx.core:core-splashscreen:${Versions.splashVersion}" const val pagingRuntime = "androidx.paging:paging-runtime:${Versions.pagingVersion}" const val workManager = "androidx.work:work-runtime-ktx:${Versions.workManagerVersion}" @@ -79,7 +81,7 @@ object ThirdPartyDependencies { } object FirebaseDependencies { - const val bom = "com.google.firebase:firebase-bom:30.1.0" + const val bom = "com.google.firebase:firebase-bom:32.2.0" const val messaging = "com.google.firebase:firebase-messaging-ktx" const val crashlytics = "com.google.firebase:firebase-crashlytics-ktx" const val analytics = "com.google.firebase:firebase-analytics-ktx" diff --git a/buildSrc/src/main/java/Plugins.kt b/buildSrc/src/main/java/Plugins.kt index 5bc44704..b8a3b271 100644 --- a/buildSrc/src/main/java/Plugins.kt +++ b/buildSrc/src/main/java/Plugins.kt @@ -3,6 +3,9 @@ object ClassPathPlugins { const val kotlinGradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlinVersion}" const val hilt = "com.google.dagger:hilt-android-gradle-plugin:${Versions.hiltVersion}" const val oss = "com.google.android.gms:oss-licenses-plugin:${Versions.ossPluginVersion}" + const val googleService = "com.google.gms:google-services:${Versions.googleServiceVersion}" + const val firebaseAppdistribution = "com.google.firebase:firebase-appdistribution-gradle:${Versions.firebaseAppdistributionVersion}" + const val firebaseCrashlytics = "com.google.firebase:firebase-crashlytics-gradle:${Versions.firebaseCrashlyticsVersion}" } object ProjectPlugins { @@ -18,4 +21,7 @@ object ModulePlugins { const val kotlinSerialization = "kotlinx-serialization" const val hilt = "dagger.hilt.android.plugin" const val oss = "com.google.android.gms.oss-licenses-plugin" + const val googleService = "com.google.gms.google-services" + const val firebaseAppdistribution = "com.google.firebase.appdistribution" + const val firebaseCrashlytics = "com.google.firebase.crashlytics" } diff --git a/buildSrc/src/main/java/Versions.kt b/buildSrc/src/main/java/Versions.kt index b79a6f00..3cb5169b 100644 --- a/buildSrc/src/main/java/Versions.kt +++ b/buildSrc/src/main/java/Versions.kt @@ -28,6 +28,8 @@ object Versions { const val exifVersion = "1.3.2" const val dataStoreVersion = "1.0.0" + const val firabaseVersion = "30.4.0" + const val coilVersion = "2.4.0" const val retrofitVersion = "2.9.0" const val kotlinSerializationConverterVersion = "1.0.0" @@ -43,6 +45,10 @@ object Versions { const val kakaoLoginVersion = "2.10.0" const val amplitudeVersion = "2.34.0" + const val googleServiceVersion = "4.3.15" + const val firebaseAppdistributionVersion = "4.0.0" + const val firebaseCrashlyticsVersion = "2.9.7" + val javaVersion = JavaVersion.VERSION_17 const val jvmVersion = "17" } From 0dcb0a2d99e9aabad921aeecff2b602dba088aad Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 13 Nov 2023 22:10:34 +0900 Subject: [PATCH 03/40] [feat] firebase gradle setting --- app/build.gradle.kts | 11 +++++++++++ build.gradle.kts | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 752698b1..92bbedbe 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -8,6 +8,9 @@ plugins { id(ModulePlugins.kotlinSerialization) id(ModulePlugins.hilt) id(ModulePlugins.oss) + id(ModulePlugins.googleService) + id(ModulePlugins.firebaseAppdistribution) + id(ModulePlugins.firebaseCrashlytics) } android { @@ -145,4 +148,12 @@ dependencies { debugImplementation(flipperLeakCanary) debugImplementation(soloader) } + + FirebaseDependencies.run { + implementation(platform(bom)) + implementation(messaging) + implementation(analytics) + implementation(crashlytics) + implementation(remoteConfig) + } } diff --git a/build.gradle.kts b/build.gradle.kts index 98513122..c6b2541c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,12 +9,16 @@ buildscript { classpath(ClassPathPlugins.kotlinGradlePlugin) classpath(ClassPathPlugins.hilt) classpath(ClassPathPlugins.oss) + classpath(ClassPathPlugins.googleService) + classpath(ClassPathPlugins.firebaseAppdistribution) + classpath(ClassPathPlugins.firebaseCrashlytics) } } plugins { id(ProjectPlugins.ktlint) version Versions.ktlintVersion id(ProjectPlugins.kotlinSerialization) version Versions.kotlinVersion + id("org.jetbrains.kotlin.android") version "1.8.20" apply false } allprojects { From 32fd741fcb8673a2642cb2be0dac365961bd6071 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 13 Nov 2023 22:35:08 +0900 Subject: [PATCH 04/40] =?UTF-8?q?[feat]=20datastore=EC=97=90=20=EB=94=94?= =?UTF-8?q?=EB=B0=94=EC=9D=B4=EC=8A=A4=20=ED=86=A0=ED=81=B0=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../winey/data/repository/DataStoreRepositoryImpl.kt | 11 +++++++++++ .../winey/domain/repository/DataStoreRepository.kt | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/app/src/main/java/org/go/sopt/winey/data/repository/DataStoreRepositoryImpl.kt b/app/src/main/java/org/go/sopt/winey/data/repository/DataStoreRepositoryImpl.kt index 434dfab5..6f81b101 100644 --- a/app/src/main/java/org/go/sopt/winey/data/repository/DataStoreRepositoryImpl.kt +++ b/app/src/main/java/org/go/sopt/winey/data/repository/DataStoreRepositoryImpl.kt @@ -37,6 +37,12 @@ class DataStoreRepositoryImpl @Inject constructor( } } + override suspend fun saveDeviceToken(deviceToken: String) { + dataStore.edit { + it[DEVICE_TOKEN] = deviceToken + } + } + override suspend fun saveUserId(userId: Int) { dataStore.edit { it[USER_ID] = userId @@ -51,6 +57,10 @@ class DataStoreRepositoryImpl @Inject constructor( return getStringValue(REFRESH_TOKEN) } + override suspend fun getDeviceToken(): Flow { + return getStringValue(DEVICE_TOKEN) + } + override suspend fun getStringValue(key: Preferences.Key): Flow { return dataStore.data .catch { exception -> @@ -119,6 +129,7 @@ class DataStoreRepositoryImpl @Inject constructor( stringPreferencesKey("social_refresh_token") private val ACCESS_TOKEN: Preferences.Key = stringPreferencesKey("access_token") private val REFRESH_TOKEN: Preferences.Key = stringPreferencesKey("refresh_token") + private val DEVICE_TOKEN: Preferences.Key = stringPreferencesKey("device_token") private val USER_ID: Preferences.Key = intPreferencesKey("user_id") private val USER_INFO: Preferences.Key = stringPreferencesKey("user_info") } diff --git a/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt b/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt index 1d993b63..47cd6108 100644 --- a/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt +++ b/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt @@ -11,12 +11,16 @@ interface DataStoreRepository { suspend fun saveAccessToken(accessToken: String = "", refreshToken: String = "") + suspend fun saveDeviceToken(deviceToken: String = "") + suspend fun saveUserId(userId: Int = 0) suspend fun getAccessToken(): Flow suspend fun getRefreshToken(): Flow + suspend fun getDeviceToken():Flow + suspend fun getStringValue(key: Preferences.Key): Flow suspend fun getUserId(): Flow From a1ce97b2e15d66366929327ed932015acc68b0f9 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 13 Nov 2023 22:35:31 +0900 Subject: [PATCH 05/40] [feat] WineyMessagingService --- app/src/main/AndroidManifest.xml | 8 ++ .../configuration/WineyMessagingService.kt | 93 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8456573b..e8bcdc28 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,6 +16,14 @@ android:theme="@style/Theme.Winey" android:usesCleartextTraffic="true" tools:targetApi="31"> + + + + + A-B + val pendingIntent = PendingIntent.getActivity( + this, + uniId, + intent, + PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_MUTABLE + ) + + // 알림 채널 이름 + val channelId = "channel" + + // 알림 소리 + val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) + + // 알림에 대한 UI 정보와 작업을 지정한다. + val notificationBuilder = NotificationCompat.Builder(this, channelId) + .setSmallIcon(R.mipmap.ic_launcher) // 아이콘 설정 + .setContentTitle(remoteMessage.data["body"].toString()) // 제목 + .setContentText(remoteMessage.data["title"].toString()) // 메시지 내용 + .setAutoCancel(true) + .setSound(soundUri) // 알림 소리 + .setContentIntent(pendingIntent) // 알림 실행 시 Intent + + val notificationManager = + getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + + // 오레오 버전 이후에는 채널이 필요하다. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channel = + NotificationChannel(channelId, "Notice", NotificationManager.IMPORTANCE_DEFAULT) + notificationManager.createNotificationChannel(channel) + } + + // 알림 생성 + notificationManager.notify(uniId, notificationBuilder.build()) + } +} From f6c64f10e1b9a1601892af151e32ad70ef020273 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 04:49:06 +0900 Subject: [PATCH 06/40] [add] #226 service lifecycleScope dependencies --- app/build.gradle.kts | 1 + buildSrc/src/main/java/Dependencies.kt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 92bbedbe..6321c961 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -105,6 +105,7 @@ dependencies { implementation(lifecycleLiveDataKtx) implementation(lifecycleViewModelKtx) implementation(lifecycleJava8) + implementation(lifecycleService) implementation(splashScreen) implementation(pagingRuntime) implementation(workManager) diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index abded618..7177dcbe 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -26,6 +26,8 @@ object AndroidXDependencies { "androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.lifecycleVersion}" const val lifecycleJava8 = "androidx.lifecycle:lifecycle-common-java8:${Versions.lifecycleVersion}" + const val lifecycleService = + "androidx.lifecycle:lifecycle-service:${Versions.lifecycleVersion}" const val ossLicense = "com.google.android.gms:play-services-oss-licenses:${Versions.ossVersion}" const val splashScreen = "androidx.core:core-splashscreen:${Versions.splashVersion}" From 6f522578fdd9b2c95dd9ca0eedfee31654460dad Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 20:40:07 +0900 Subject: [PATCH 07/40] =?UTF-8?q?[mod]=20#226=20=ED=8C=8C=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EB=B2=A0=EC=9D=B4=EC=8A=A4=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuration/WineyMessagingService.kt | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt index e274dc15..fd6490fd 100644 --- a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt +++ b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt @@ -12,7 +12,8 @@ import androidx.core.app.NotificationCompat import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import org.go.sopt.winey.R import org.go.sopt.winey.domain.repository.DataStoreRepository import org.go.sopt.winey.presentation.main.MainActivity @@ -29,28 +30,33 @@ class WineyMessagingService : FirebaseMessagingService() { override fun onNewToken(token: String) { super.onNewToken(token) - Log.i("토큰: ", token) - runBlocking { dataStoreRepository.saveDeviceToken(token) } + Log.i(TAG, token) + GlobalScope.launch { dataStoreRepository.saveDeviceToken(token) } } override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) Log.d(TAG, "From: " + remoteMessage!!.from) + Log.d(TAG,"${remoteMessage.from}") + + Log.d(TAG, "Notification Message Body: ${remoteMessage.notification?.body}") if (remoteMessage.data.isNotEmpty()) { - Log.i("바디: ", remoteMessage.data["body"].toString()) - Log.i("타이틀: ", remoteMessage.data["title"].toString()) + Log.i(TAG, remoteMessage.data["body"].toString()) + Log.i(TAG, remoteMessage.data["title"].toString()) + Log.d(TAG, "Data Payload: " + remoteMessage.data) sendNotification(remoteMessage) + Log.d(TAG,remoteMessage.data["feedId"]!!) } else { - Log.i("수신에러: ", "data가 비어있습니다. 메시지를 수신하지 못했습니다.") - Log.i("data값: ", remoteMessage.data.toString()) + Log.i(TAG, "data가 비어있습니다. 메시지를 수신하지 못했습니다.") + Log.i(TAG, remoteMessage.data.toString()) } } private fun sendNotification(remoteMessage: RemoteMessage) { // RequestCode, Id를 고유값으로 지정하여 알림이 개별 표시되도록 함 val uniId: Int = (System.currentTimeMillis() / 7).toInt() - + Log.d(TAG,remoteMessage.toString()) // 일회용 PendingIntent // PendingIntent : Intent 의 실행 권한을 외부의 어플리케이션에게 위임한다. val intent = Intent(this, MainActivity::class.java) From 73fa15ca43c90af507304fc5bb45cceb823275ec Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 20:40:59 +0900 Subject: [PATCH 08/40] =?UTF-8?q?[add]=20#226=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20=EB=A6=AC=EC=86=8C=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/drawable/ic_mypage_switch_ellipse.xml | 9 +++++++++ .../res/drawable/ic_mypage_switch_off_background.xml | 9 +++++++++ .../res/drawable/ic_mypage_switch_on_background.xml | 9 +++++++++ app/src/main/res/drawable/ic_mypage_switchoff.xml | 12 ++++++++++++ app/src/main/res/drawable/ic_mypage_switchon.xml | 12 ++++++++++++ 5 files changed, 51 insertions(+) create mode 100644 app/src/main/res/drawable/ic_mypage_switch_ellipse.xml create mode 100644 app/src/main/res/drawable/ic_mypage_switch_off_background.xml create mode 100644 app/src/main/res/drawable/ic_mypage_switch_on_background.xml create mode 100644 app/src/main/res/drawable/ic_mypage_switchoff.xml create mode 100644 app/src/main/res/drawable/ic_mypage_switchon.xml diff --git a/app/src/main/res/drawable/ic_mypage_switch_ellipse.xml b/app/src/main/res/drawable/ic_mypage_switch_ellipse.xml new file mode 100644 index 00000000..9b6275b9 --- /dev/null +++ b/app/src/main/res/drawable/ic_mypage_switch_ellipse.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_mypage_switch_off_background.xml b/app/src/main/res/drawable/ic_mypage_switch_off_background.xml new file mode 100644 index 00000000..a4091c5c --- /dev/null +++ b/app/src/main/res/drawable/ic_mypage_switch_off_background.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_mypage_switch_on_background.xml b/app/src/main/res/drawable/ic_mypage_switch_on_background.xml new file mode 100644 index 00000000..2a60e903 --- /dev/null +++ b/app/src/main/res/drawable/ic_mypage_switch_on_background.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_mypage_switchoff.xml b/app/src/main/res/drawable/ic_mypage_switchoff.xml new file mode 100644 index 00000000..3d1fef8f --- /dev/null +++ b/app/src/main/res/drawable/ic_mypage_switchoff.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_mypage_switchon.xml b/app/src/main/res/drawable/ic_mypage_switchon.xml new file mode 100644 index 00000000..1c061691 --- /dev/null +++ b/app/src/main/res/drawable/ic_mypage_switchon.xml @@ -0,0 +1,12 @@ + + + + From d90a1b532c3fde16c30849e52bd6b8e894334eb7 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 20:41:26 +0900 Subject: [PATCH 09/40] =?UTF-8?q?[feat]=20#226=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=8A=A4=EC=9C=84=EC=B9=98=20=EB=AA=A8?= =?UTF-8?q?=EC=85=98=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/fragment_my_page.xml | 67 ++++++++++++++++- ...ment_my_page_xml_cl_mypage_agree_scene.xml | 72 +++++++++++++++++++ 2 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/xml/fragment_my_page_xml_cl_mypage_agree_scene.xml diff --git a/app/src/main/res/layout/fragment_my_page.xml b/app/src/main/res/layout/fragment_my_page.xml index 71d7428d..53f5283c 100644 --- a/app/src/main/res/layout/fragment_my_page.xml +++ b/app/src/main/res/layout/fragment_my_page.xml @@ -355,13 +355,78 @@ android:background="@color/gray_50" app:layout_constraintTop_toBottomOf="@id/cl_mypage_to_myfeed" /> + + + + + + + + + + + + + + + + app:layout_constraintTop_toBottomOf="@id/v_mypage_line10"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From c3cdaa0fbce70951e971d7ed9c0f5467f8f05f7b Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 20:42:00 +0900 Subject: [PATCH 10/40] =?UTF-8?q?[feat]=20#226=20=EC=8A=A4=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EC=83=81=ED=83=9C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../winey/presentation/main/mypage/MyPageFragment.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt index f37b4f77..2d874cc7 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt @@ -250,6 +250,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ binding.data = data updateTargetInfo(data) updateUserLevel(data) + updateSwitchState(data) } private fun updateTargetInfo(data: User) { @@ -292,6 +293,17 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ } } + private fun updateSwitchState(data: User) { + when(data.fcmIsAllowed) { + true -> { + binding.ivMypageAgree.transitionToEnd() + } + false -> { + binding.ivMypageAgree.transitionToStart() + } + } + } + private fun initTargetModifyButtonClickListener(user: User) { binding.clMypageTargetmoney.setOnSingleClickListener { amplitudeUtils.logEvent("click_goalsetting") From 01918bb7d9c2e95f246820b40038e426d1e768ee Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 20:42:29 +0900 Subject: [PATCH 11/40] =?UTF-8?q?[chore]=20#226=20ResponseGetUserDto=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../winey/data/model/remote/response/ResponseGetUserDto.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt b/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt index e06bfb92..0d303a85 100644 --- a/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt +++ b/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt @@ -36,7 +36,9 @@ data class ResponseGetUserDto( @SerialName("userId") val userId: Int, @SerialName("userLevel") - val userLevel: String + val userLevel: String, + @SerialName("fcmIsAllowed") + val fcmIsAllowed: Boolean ) fun toUser(): User { @@ -46,6 +48,7 @@ data class ResponseGetUserDto( return User( nickname = userResponseUserDto?.nickname.orEmpty(), userLevel = userResponseUserDto?.userLevel.orEmpty(), + fcmIsAllowed = userResponseUserDto?.fcmIsAllowed ?: false, duringGoalAmount = data.userResponseGoalDto?.duringGoalAmount ?: 0, duringGoalCount = data.userResponseGoalDto?.duringGoalCount ?: 0, targetMoney = data.userResponseGoalDto?.targetMoney ?: 0, From 9eebf99f33153130a30f6dc437dfc5e7729f287f Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 20:42:49 +0900 Subject: [PATCH 12/40] =?UTF-8?q?[feat]=20#226=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20Dto=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/RequestPatchAllowedNotificationDto.kt | 10 ++++++++++ .../response/ResponsePatchAllowedNotificationDto.kt | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 app/src/main/java/org/go/sopt/winey/data/model/remote/request/RequestPatchAllowedNotificationDto.kt create mode 100644 app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponsePatchAllowedNotificationDto.kt diff --git a/app/src/main/java/org/go/sopt/winey/data/model/remote/request/RequestPatchAllowedNotificationDto.kt b/app/src/main/java/org/go/sopt/winey/data/model/remote/request/RequestPatchAllowedNotificationDto.kt new file mode 100644 index 00000000..3a05dc19 --- /dev/null +++ b/app/src/main/java/org/go/sopt/winey/data/model/remote/request/RequestPatchAllowedNotificationDto.kt @@ -0,0 +1,10 @@ +package org.go.sopt.winey.data.model.remote.request + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RequestPatchAllowedNotificationDto( + @SerialName("allowedPush") + val allowedPush: Boolean +) diff --git a/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponsePatchAllowedNotificationDto.kt b/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponsePatchAllowedNotificationDto.kt new file mode 100644 index 00000000..0415ef7f --- /dev/null +++ b/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponsePatchAllowedNotificationDto.kt @@ -0,0 +1,10 @@ +package org.go.sopt.winey.data.model.remote.response + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponsePatchAllowedNotificationDto( + @SerialName("fcmIsAllowed") + val fcmIsAllowed: Boolean +) From 1869607aabc44d89c953922a3071cc792f9e8bb8 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 20:43:10 +0900 Subject: [PATCH 13/40] =?UTF-8?q?[chore]=20#226=20domain=20User=20?= =?UTF-8?q?=EC=97=94=ED=84=B0=ED=8B=B0=20=EC=95=8C=EB=A6=BC=EB=8F=99?= =?UTF-8?q?=EC=9D=98=EC=97=AC=EB=B6=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/org/go/sopt/winey/domain/entity/User.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/go/sopt/winey/domain/entity/User.kt b/app/src/main/java/org/go/sopt/winey/domain/entity/User.kt index 6301cec3..5b031f0e 100644 --- a/app/src/main/java/org/go/sopt/winey/domain/entity/User.kt +++ b/app/src/main/java/org/go/sopt/winey/domain/entity/User.kt @@ -3,6 +3,7 @@ package org.go.sopt.winey.domain.entity data class User( val nickname: String = "", val userLevel: String = "", + val fcmIsAllowed: Boolean = false, val duringGoalAmount: Long = 0, val duringGoalCount: Long = 0, val targetMoney: Int = 0, From 46949f1dc6a2d0972c0938cc50e1421aff326750 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 21:46:11 +0900 Subject: [PATCH 14/40] =?UTF-8?q?[feat]=20#226=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=EB=8F=99=EC=9D=98=20=EC=97=AC=EB=B6=80=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/go/sopt/winey/data/service/AuthService.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/org/go/sopt/winey/data/service/AuthService.kt b/app/src/main/java/org/go/sopt/winey/data/service/AuthService.kt index ca4600b4..7c088b1c 100644 --- a/app/src/main/java/org/go/sopt/winey/data/service/AuthService.kt +++ b/app/src/main/java/org/go/sopt/winey/data/service/AuthService.kt @@ -2,12 +2,14 @@ package org.go.sopt.winey.data.service import org.go.sopt.winey.data.model.remote.request.RequestCreateGoalDto import org.go.sopt.winey.data.model.remote.request.RequestLoginDto +import org.go.sopt.winey.data.model.remote.request.RequestPatchAllowedNotificationDto import org.go.sopt.winey.data.model.remote.request.RequestPatchNicknameDto import org.go.sopt.winey.data.model.remote.response.ResponseCreateGoalDto import org.go.sopt.winey.data.model.remote.response.ResponseGetNicknameDuplicateCheckDto import org.go.sopt.winey.data.model.remote.response.ResponseGetUserDto import org.go.sopt.winey.data.model.remote.response.ResponseLoginDto import org.go.sopt.winey.data.model.remote.response.ResponseLogoutDto +import org.go.sopt.winey.data.model.remote.response.ResponsePatchAllowedNotificationDto import org.go.sopt.winey.data.model.remote.response.ResponseReIssueTokenDto import org.go.sopt.winey.data.model.remote.response.base.BaseResponse import retrofit2.http.Body @@ -53,4 +55,9 @@ interface AuthService { suspend fun patchNickname( @Body requestPatchNicknameDto: RequestPatchNicknameDto ): BaseResponse + + @PATCH("user/notification") + suspend fun patchAllowedNotification( + @Body requestPatchAllowedNotificationDto: RequestPatchAllowedNotificationDto + ): BaseResponse } From a40c5758d68bb3304182af4301aab5a8aa75e63f Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 21:46:23 +0900 Subject: [PATCH 15/40] =?UTF-8?q?[feat]=20#226=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=EB=8F=99=EC=9D=98=20=EC=97=AC=EB=B6=80=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?datasource?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/go/sopt/winey/data/source/AuthDataSource.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/org/go/sopt/winey/data/source/AuthDataSource.kt b/app/src/main/java/org/go/sopt/winey/data/source/AuthDataSource.kt index a53068fa..acfe0167 100644 --- a/app/src/main/java/org/go/sopt/winey/data/source/AuthDataSource.kt +++ b/app/src/main/java/org/go/sopt/winey/data/source/AuthDataSource.kt @@ -2,12 +2,14 @@ package org.go.sopt.winey.data.source import org.go.sopt.winey.data.model.remote.request.RequestCreateGoalDto import org.go.sopt.winey.data.model.remote.request.RequestLoginDto +import org.go.sopt.winey.data.model.remote.request.RequestPatchAllowedNotificationDto import org.go.sopt.winey.data.model.remote.request.RequestPatchNicknameDto import org.go.sopt.winey.data.model.remote.response.ResponseCreateGoalDto import org.go.sopt.winey.data.model.remote.response.ResponseGetNicknameDuplicateCheckDto import org.go.sopt.winey.data.model.remote.response.ResponseGetUserDto import org.go.sopt.winey.data.model.remote.response.ResponseLoginDto import org.go.sopt.winey.data.model.remote.response.ResponseLogoutDto +import org.go.sopt.winey.data.model.remote.response.ResponsePatchAllowedNotificationDto import org.go.sopt.winey.data.model.remote.response.ResponseReIssueTokenDto import org.go.sopt.winey.data.model.remote.response.base.BaseResponse import org.go.sopt.winey.data.service.AuthService @@ -43,4 +45,9 @@ class AuthDataSource @Inject constructor( requestPatchNicknameDto: RequestPatchNicknameDto ): BaseResponse = authService.patchNickname(requestPatchNicknameDto) + + suspend fun patchAllowedNotification( + requestPatchAllowedNotificationDto: RequestPatchAllowedNotificationDto + ): BaseResponse = + authService.patchAllowedNotification(requestPatchAllowedNotificationDto) } From 6228ae9f87a1aa11ad8dd798a24593a098be74e8 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 21:46:33 +0900 Subject: [PATCH 16/40] =?UTF-8?q?[feat]=20#226=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=EB=8F=99=EC=9D=98=20=EC=97=AC=EB=B6=80=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?repository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt | 6 ++++++ .../org/go/sopt/winey/domain/repository/AuthRepository.kt | 2 ++ 2 files changed, 8 insertions(+) diff --git a/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt b/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt index 16d20ccf..44bd7519 100644 --- a/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt +++ b/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt @@ -2,6 +2,7 @@ package org.go.sopt.winey.data.repository import org.go.sopt.winey.data.model.remote.request.RequestCreateGoalDto import org.go.sopt.winey.data.model.remote.request.RequestLoginDto +import org.go.sopt.winey.data.model.remote.request.RequestPatchAllowedNotificationDto import org.go.sopt.winey.data.model.remote.request.RequestPatchNicknameDto import org.go.sopt.winey.data.model.remote.response.ResponseGetNicknameDuplicateCheckDto import org.go.sopt.winey.data.model.remote.response.ResponseLoginDto @@ -60,4 +61,9 @@ class AuthRepositoryImpl @Inject constructor( runCatching { authDataSource.patchNickname(requestPatchNicknameDto).data } + + override suspend fun patchAllowedNotification(request: Boolean): Result = + runCatching { + authDataSource.patchAllowedNotification(RequestPatchAllowedNotificationDto(allowedPush = request)).data?.isAllowed + } } diff --git a/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt b/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt index 2819df03..5a31db61 100644 --- a/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt +++ b/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt @@ -29,4 +29,6 @@ interface AuthRepository { suspend fun getNicknameDuplicateCheck(nickname: String): Result suspend fun patchNickname(requestPatchNicknameDto: RequestPatchNicknameDto): Result + + suspend fun patchAllowedNotification(request: Boolean): Result } From 768942c102760e47312a2b5535b2a54f3550cb8a Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 21:46:53 +0900 Subject: [PATCH 17/40] =?UTF-8?q?[chore]=20#226=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=EB=8F=99=EC=9D=98=EC=97=AC=EB=B6=80=20=EB=B3=80=EA=B2=BD=20res?= =?UTF-8?q?ponse=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../remote/response/ResponsePatchAllowedNotificationDto.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponsePatchAllowedNotificationDto.kt b/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponsePatchAllowedNotificationDto.kt index 0415ef7f..b46217ce 100644 --- a/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponsePatchAllowedNotificationDto.kt +++ b/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponsePatchAllowedNotificationDto.kt @@ -5,6 +5,6 @@ import kotlinx.serialization.Serializable @Serializable data class ResponsePatchAllowedNotificationDto( - @SerialName("fcmIsAllowed") - val fcmIsAllowed: Boolean + @SerialName("isAllowed") + val isAllowed: Boolean ) From 4f3623a29081ba9b650533d2167f955d7eeac54c Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 21:47:27 +0900 Subject: [PATCH 18/40] =?UTF-8?q?[feat]=20#226=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=EB=8F=99=EC=9D=98=20=EC=97=AC=EB=B6=80=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/mypage/MyPageViewModel.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt index 6ff87f59..ed64c4ae 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt @@ -22,6 +22,9 @@ class MyPageViewModel @Inject constructor( private val _deleteUserState = MutableStateFlow>(UiState.Empty) val deleteUserState: StateFlow> = _deleteUserState.asStateFlow() + private val _patchAllowedNotificationState = MutableStateFlow>(UiState.Empty) + val patchAllowedNotificationState: StateFlow> = _patchAllowedNotificationState.asStateFlow() + fun deleteUser() { viewModelScope.launch { authRepository.deleteUser() @@ -42,6 +45,26 @@ class MyPageViewModel @Inject constructor( } } + fun patchAllowedNotification(isAllowed: Boolean) { + viewModelScope.launch { + authRepository.patchAllowedNotification(!isAllowed) + .onSuccess { response -> + Timber.d("SUCCESS PATCH ALLOWED NOTI") + _patchAllowedNotificationState.value = UiState.Success(response) + } + .onFailure {t -> + _patchAllowedNotificationState.value = UiState.Failure(t.message.toString()) + + if (t is HttpException) { + Timber.e("HTTP FAIL ALLOWED NOTI : ${t.code()} ${t.message}") + return@onFailure + } + + Timber.e("FAIL ALLOWED NOTI : ${t.message}") + } + } + } + fun clearDataStore() { viewModelScope.launch { dataStoreRepository.clearDataStore() From 30f3eabe4cba53d61381512c824d217b06ec98cb Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Mon, 20 Nov 2023 23:30:29 +0900 Subject: [PATCH 19/40] =?UTF-8?q?[feat]=20#226=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=EB=8F=99=EC=9D=98=EC=97=AC=EB=B6=80=20=EB=B3=80=EA=B2=BD=20ui?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/mypage/MyPageFragment.kt | 62 ++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt index 2d874cc7..7ded1049 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt @@ -63,13 +63,72 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ initLogoutButtonClickListener() initWithdrawButtonClickListener() initNicknameButtonClickListener() + initAllowedNotificationButtonClickListener() registerBackPressedCallback() setupGetUserState() setupDeleteUserState() + setupPatchAllowedNotificationState() + checkFromWineyFeed() } + private fun setupPatchAllowedNotificationState() { + myPageViewModel.patchAllowedNotificationState.flowWithLifecycle(lifecycle).onEach { state -> + when (state) { + is UiState.Success -> { + when (state.data) { + true -> { + binding.ivMypageAgree.transitionToEnd() + } + + false -> { + binding.ivMypageAgree.transitionToStart() + } + + null -> { + binding.ivMypageAgree.transitionToStart() + } + } + } + + is UiState.Failure -> {} + is UiState.Empty -> {} + else -> {} + } + } + } + + private fun initAllowedNotificationButtonClickListener() { + binding.ivMypageSwitch.setOnClickListener { + val isAllowed = when (binding.ivMypageAgree.currentState) { + R.id.start -> false + R.id.end -> true + else -> false + } + when (isAllowed) { + true -> { + binding.ivMypageAgree.transitionToStart() + lifecycleScope.launch { + val data = dataStoreRepository.getUserInfo().first() + val newData = data?.copy(fcmIsAllowed = false) + dataStoreRepository.saveUserInfo(newData) + } + } + + false -> { + binding.ivMypageAgree.transitionToEnd() + lifecycleScope.launch { + val data = dataStoreRepository.getUserInfo().first() + val newData = data?.copy(fcmIsAllowed = true) + dataStoreRepository.saveUserInfo(newData) + } + } + } + myPageViewModel.patchAllowedNotification(isAllowed) + } + } + // 닉네임 액티비티 갔다가 다시 돌아왔을 때 유저 데이터 갱신하도록 override fun onStart() { super.onStart() @@ -294,10 +353,11 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ } private fun updateSwitchState(data: User) { - when(data.fcmIsAllowed) { + when (data.fcmIsAllowed) { true -> { binding.ivMypageAgree.transitionToEnd() } + false -> { binding.ivMypageAgree.transitionToStart() } From 2c357664b7ad384aea1e75b1f8947a420869a6cf Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 01:51:51 +0900 Subject: [PATCH 20/40] =?UTF-8?q?[feat]=20fcm=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=ED=8C=A8=EC=B9=98=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/remote/request/RequestPatchFcmTokenDto.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 app/src/main/java/org/go/sopt/winey/data/model/remote/request/RequestPatchFcmTokenDto.kt diff --git a/app/src/main/java/org/go/sopt/winey/data/model/remote/request/RequestPatchFcmTokenDto.kt b/app/src/main/java/org/go/sopt/winey/data/model/remote/request/RequestPatchFcmTokenDto.kt new file mode 100644 index 00000000..23590fd7 --- /dev/null +++ b/app/src/main/java/org/go/sopt/winey/data/model/remote/request/RequestPatchFcmTokenDto.kt @@ -0,0 +1,10 @@ +package org.go.sopt.winey.data.model.remote.request + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RequestPatchFcmTokenDto( + @SerialName("token") + val fcmToken: String +) From 9ea1a46393532d553caf31d4834e88f59d2ae4d0 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 01:52:06 +0900 Subject: [PATCH 21/40] =?UTF-8?q?[feat]=20fcm=20token=20patch=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/go/sopt/winey/data/service/AuthService.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/org/go/sopt/winey/data/service/AuthService.kt b/app/src/main/java/org/go/sopt/winey/data/service/AuthService.kt index 7c088b1c..95555140 100644 --- a/app/src/main/java/org/go/sopt/winey/data/service/AuthService.kt +++ b/app/src/main/java/org/go/sopt/winey/data/service/AuthService.kt @@ -3,6 +3,7 @@ package org.go.sopt.winey.data.service import org.go.sopt.winey.data.model.remote.request.RequestCreateGoalDto import org.go.sopt.winey.data.model.remote.request.RequestLoginDto import org.go.sopt.winey.data.model.remote.request.RequestPatchAllowedNotificationDto +import org.go.sopt.winey.data.model.remote.request.RequestPatchFcmTokenDto import org.go.sopt.winey.data.model.remote.request.RequestPatchNicknameDto import org.go.sopt.winey.data.model.remote.response.ResponseCreateGoalDto import org.go.sopt.winey.data.model.remote.response.ResponseGetNicknameDuplicateCheckDto @@ -60,4 +61,9 @@ interface AuthService { suspend fun patchAllowedNotification( @Body requestPatchAllowedNotificationDto: RequestPatchAllowedNotificationDto ): BaseResponse + + @PATCH("user/fcmtoken") + suspend fun patchFcmToken( + @Body requestPatchFcmTokenDto: RequestPatchFcmTokenDto + ): BaseResponse } From 38b24d34816426408a055967323cf3d5f6b2066c Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 01:53:25 +0900 Subject: [PATCH 22/40] =?UTF-8?q?[feat]=20fcm=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=ED=8C=A8=EC=B9=98=20datasource?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/go/sopt/winey/data/source/AuthDataSource.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/org/go/sopt/winey/data/source/AuthDataSource.kt b/app/src/main/java/org/go/sopt/winey/data/source/AuthDataSource.kt index acfe0167..18e0e4fb 100644 --- a/app/src/main/java/org/go/sopt/winey/data/source/AuthDataSource.kt +++ b/app/src/main/java/org/go/sopt/winey/data/source/AuthDataSource.kt @@ -3,6 +3,7 @@ package org.go.sopt.winey.data.source import org.go.sopt.winey.data.model.remote.request.RequestCreateGoalDto import org.go.sopt.winey.data.model.remote.request.RequestLoginDto import org.go.sopt.winey.data.model.remote.request.RequestPatchAllowedNotificationDto +import org.go.sopt.winey.data.model.remote.request.RequestPatchFcmTokenDto import org.go.sopt.winey.data.model.remote.request.RequestPatchNicknameDto import org.go.sopt.winey.data.model.remote.response.ResponseCreateGoalDto import org.go.sopt.winey.data.model.remote.response.ResponseGetNicknameDuplicateCheckDto @@ -50,4 +51,9 @@ class AuthDataSource @Inject constructor( requestPatchAllowedNotificationDto: RequestPatchAllowedNotificationDto ): BaseResponse = authService.patchAllowedNotification(requestPatchAllowedNotificationDto) + + suspend fun patchFcmToken( + requestPatchFcmTokenDto: RequestPatchFcmTokenDto + ): BaseResponse = + authService.patchFcmToken(requestPatchFcmTokenDto) } From 8f30fc26e1a353c5eb5338dafeb5f57abc3aa99d Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 01:53:47 +0900 Subject: [PATCH 23/40] =?UTF-8?q?[feat]=20fcm=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=ED=8C=A8=EC=B9=98=20repository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt | 6 ++++++ .../org/go/sopt/winey/domain/repository/AuthRepository.kt | 2 ++ 2 files changed, 8 insertions(+) diff --git a/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt b/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt index 44bd7519..d99e6a9e 100644 --- a/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt +++ b/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt @@ -3,6 +3,7 @@ package org.go.sopt.winey.data.repository import org.go.sopt.winey.data.model.remote.request.RequestCreateGoalDto import org.go.sopt.winey.data.model.remote.request.RequestLoginDto import org.go.sopt.winey.data.model.remote.request.RequestPatchAllowedNotificationDto +import org.go.sopt.winey.data.model.remote.request.RequestPatchFcmTokenDto import org.go.sopt.winey.data.model.remote.request.RequestPatchNicknameDto import org.go.sopt.winey.data.model.remote.response.ResponseGetNicknameDuplicateCheckDto import org.go.sopt.winey.data.model.remote.response.ResponseLoginDto @@ -66,4 +67,9 @@ class AuthRepositoryImpl @Inject constructor( runCatching { authDataSource.patchAllowedNotification(RequestPatchAllowedNotificationDto(allowedPush = request)).data?.isAllowed } + + override suspend fun patchFcmToken(token: String): Result = + runCatching { + authDataSource.patchFcmToken(RequestPatchFcmTokenDto(fcmToken = token)) + } } diff --git a/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt b/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt index 5a31db61..ac4dbd3a 100644 --- a/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt +++ b/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt @@ -31,4 +31,6 @@ interface AuthRepository { suspend fun patchNickname(requestPatchNicknameDto: RequestPatchNicknameDto): Result suspend fun patchAllowedNotification(request: Boolean): Result + + suspend fun patchFcmToken(token: String): Result } From 52c2089376a694ddf530c5a2e3daaf389c415e3e Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 01:57:27 +0900 Subject: [PATCH 24/40] =?UTF-8?q?[feat]=20patchFcmToken=20=EB=B7=B0?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../winey/presentation/main/MainViewModel.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt index 32e74a0f..6f005aa8 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt @@ -8,6 +8,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import org.go.sopt.winey.data.model.remote.response.ResponseLogoutDto import org.go.sopt.winey.domain.entity.User @@ -113,6 +114,25 @@ class MainViewModel @Inject constructor( } } + fun patchFcmToken() { + viewModelScope.launch { + val token = dataStoreRepository.getDeviceToken().first() + if(token.isNullOrBlank()){ + return@launch + } + authRepository.patchFcmToken(token) + .onSuccess { + Timber.e("디바이스 토큰 보내기 성공") + } + .onFailure { t -> + if (t is HttpException) { + Timber.e("HTTP 실패") + } + Timber.e("${t.message}") + } + } + } + companion object { private const val CODE_TOKEN_EXPIRED = 401 } From 173d49f4e59e201d5855d4e518f434022f9f0652 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 02:01:23 +0900 Subject: [PATCH 25/40] =?UTF-8?q?[mod]=20firebase=20messaging=20service=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuration/WineyMessagingService.kt | 64 ++++++++----------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt index fd6490fd..b9650d6e 100644 --- a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt +++ b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt @@ -7,93 +7,83 @@ import android.content.Context import android.content.Intent import android.media.RingtoneManager import android.os.Build -import android.util.Log import androidx.core.app.NotificationCompat import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.go.sopt.winey.R import org.go.sopt.winey.domain.repository.DataStoreRepository -import org.go.sopt.winey.presentation.main.MainActivity +import org.go.sopt.winey.presentation.splash.SplashActivity import javax.inject.Inject @AndroidEntryPoint class WineyMessagingService : FirebaseMessagingService() { - private val TAG = "FirebaseService" - @Inject lateinit var dataStoreRepository: DataStoreRepository override fun onNewToken(token: String) { super.onNewToken(token) - Log.i(TAG, token) - GlobalScope.launch { dataStoreRepository.saveDeviceToken(token) } + CoroutineScope(Dispatchers.IO).launch { dataStoreRepository.saveDeviceToken(token) } } override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) - Log.d(TAG, "From: " + remoteMessage!!.from) - Log.d(TAG,"${remoteMessage.from}") - - Log.d(TAG, "Notification Message Body: ${remoteMessage.notification?.body}") if (remoteMessage.data.isNotEmpty()) { - Log.i(TAG, remoteMessage.data["body"].toString()) - Log.i(TAG, remoteMessage.data["title"].toString()) - Log.d(TAG, "Data Payload: " + remoteMessage.data) sendNotification(remoteMessage) - Log.d(TAG,remoteMessage.data["feedId"]!!) - } else { - Log.i(TAG, "data가 비어있습니다. 메시지를 수신하지 못했습니다.") - Log.i(TAG, remoteMessage.data.toString()) } } private fun sendNotification(remoteMessage: RemoteMessage) { - // RequestCode, Id를 고유값으로 지정하여 알림이 개별 표시되도록 함 val uniId: Int = (System.currentTimeMillis() / 7).toInt() - Log.d(TAG,remoteMessage.toString()) - // 일회용 PendingIntent - // PendingIntent : Intent 의 실행 권한을 외부의 어플리케이션에게 위임한다. - val intent = Intent(this, MainActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) // Activity Stack 을 경로만 남긴다. A-B-C-D-B => A-B + + val intent = Intent(this, SplashActivity::class.java) + intent.putExtra(KEY_NOTI_TYPE, remoteMessage.data[KEY_NOTI_TYPE]) + intent.putExtra(KEY_FEED_ID, remoteMessage.data[KEY_FEED_ID]) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) val pendingIntent = PendingIntent.getActivity( this, uniId, intent, - PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_MUTABLE + PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE, ) - // 알림 채널 이름 - val channelId = "channel" + val channelId = CHANNEL_ID - // 알림 소리 val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) - // 알림에 대한 UI 정보와 작업을 지정한다. val notificationBuilder = NotificationCompat.Builder(this, channelId) - .setSmallIcon(R.mipmap.ic_launcher) // 아이콘 설정 - .setContentTitle(remoteMessage.data["body"].toString()) // 제목 - .setContentText(remoteMessage.data["title"].toString()) // 메시지 내용 + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle(remoteMessage.data[KEY_TITLE]) + .setContentText(remoteMessage.data[KEY_MESSAGE]) .setAutoCancel(true) - .setSound(soundUri) // 알림 소리 - .setContentIntent(pendingIntent) // 알림 실행 시 Intent + .setSound(soundUri) + .setContentIntent(pendingIntent) val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - // 오레오 버전 이후에는 채널이 필요하다. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = - NotificationChannel(channelId, "Notice", NotificationManager.IMPORTANCE_DEFAULT) + NotificationChannel(channelId, NOTICE, NotificationManager.IMPORTANCE_DEFAULT) notificationManager.createNotificationChannel(channel) } - // 알림 생성 notificationManager.notify(uniId, notificationBuilder.build()) } + + companion object { + private const val TAG = "FirebaseService" + private const val KEY_FEED_ID = "feedId" + private const val KEY_NOTI_TYPE = "notiType" + private const val KEY_TITLE = "title" + private const val KEY_MESSAGE = "message" + private const val NOTICE = "Notice" + private const val CHANNEL_ID = "channel" + } } From cb3439825452bacf1110d148773e8194ead8d4e6 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 02:01:36 +0900 Subject: [PATCH 26/40] =?UTF-8?q?[feat]=20=EC=95=8C=EB=A6=BC=20=EB=B6=84?= =?UTF-8?q?=EA=B8=B0=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../winey/presentation/main/MainActivity.kt | 50 ++++++++++++++++++- .../presentation/splash/SplashActivity.kt | 15 +++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt index cf64e383..11e78cba 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt @@ -14,7 +14,9 @@ import kotlinx.coroutines.flow.onEach import org.go.sopt.winey.R import org.go.sopt.winey.databinding.ActivityMainBinding import org.go.sopt.winey.presentation.main.feed.WineyFeedFragment +import org.go.sopt.winey.presentation.main.feed.detail.DetailActivity import org.go.sopt.winey.presentation.main.mypage.MyPageFragment +import org.go.sopt.winey.presentation.main.mypage.MypageHelpActivity import org.go.sopt.winey.presentation.main.recommend.RecommendFragment import org.go.sopt.winey.presentation.onboarding.login.LoginActivity import org.go.sopt.winey.util.binding.BindingActivity @@ -30,13 +32,15 @@ class MainActivity : BindingActivity(R.layout.activity_main private val isDeleteSuccess by lazy { intent.extras?.getBoolean(EXTRA_DELETE_KEY, false) } private val isReportSuccess by lazy { intent.extras?.getBoolean(EXTRA_REPORT_KEY, false) } private val prevScreenName by lazy { intent.extras?.getString(KEY_PREV_SCREEN, "") } - + private val notiType by lazy { intent.extras?.getString(KEY_NOTI_TYPE,"") } + private val feedId by lazy { intent.extras?.getString(KEY_FEED_ID) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 위니피드, 마이페이지 프래그먼트에서 getUserState 관찰 mainViewModel.getUser() - + mainViewModel.patchFcmToken() + initNotiTypeHandler() initFragment() initBnvItemSelectedListener() syncBottomNavigationSelection() @@ -45,6 +49,22 @@ class MainActivity : BindingActivity(R.layout.activity_main showSuccessSnackBar() } + private fun initNotiTypeHandler() { + when (notiType) { + KEY_RANKUP_TO_2, KEY_RANKUP_TO_3, KEY_RANKUP_TO_4 -> navigateToMyPageWithBundle(KEY_FROM_NOTI, true) + KEY_RANKDOWN_TO_1, KEY_RANKDOWN_TO_2, KEY_RANKDOWN_TO_3 -> navigateToMyPageWithBundle( + KEY_FROM_NOTI, + true + ) + + KEY_GOAL_FAILED -> navigateToMyPageWithBundle(KEY_FROM_NOTI, true) + KEY_LIKE_NOTI -> navigateToDetail(feedId?.toInt()) + KEY_COMMENT_NOTI -> navigateToDetail(feedId?.toInt()) + KEY_HOW_TO_LEVELUP -> navigateToLevelupHelp() + else -> null + } + } + private fun initFragment() { if (intent.getBooleanExtra(KEY_TO_MYPAGE, false)) { navigateToMyPageWithBundle(KEY_FROM_NOTI, true) @@ -140,16 +160,42 @@ class MainActivity : BindingActivity(R.layout.activity_main } } + private fun navigateToDetail(feedId: Int?) { + val intent = Intent(this, DetailActivity::class.java) + intent.putExtra(KEY_FEED_ID, feedId) + startActivity(intent) + } + + private fun navigateToLevelupHelp() { + val intent = Intent(this, MypageHelpActivity::class.java) + startActivity(intent) + } + companion object { private const val EXTRA_UPLOAD_KEY = "upload" private const val EXTRA_DELETE_KEY = "delete" private const val EXTRA_REPORT_KEY = "report" + private const val KEY_FEED_ID = "feedId" + private const val KEY_NOTI_TYPE = "notiType" private const val KEY_PREV_SCREEN = "PREV_SCREEN_NAME" private const val KEY_FROM_NOTI = "fromNoti" private const val KEY_TO_MYFEED = "toMyFeed" private const val KEY_TO_MYPAGE = "navigateMypage" + private const val KEY_RANKUP_TO_2 = "RANKUPTO2" + private const val KEY_RANKUP_TO_3 = "RANKUPTO3" + private const val KEY_RANKUP_TO_4 = "RANKUPTO4" + + private const val KEY_RANKDOWN_TO_1 = "DELETERANKDOWNTO1" + private const val KEY_RANKDOWN_TO_2 = "DELETERANKDOWNTO2" + private const val KEY_RANKDOWN_TO_3 = "DELETERANKDOWNTO3" + + private const val KEY_GOAL_FAILED = "GOALFAILED" + private const val KEY_LIKE_NOTI = "LIKENOTI" + private const val KEY_COMMENT_NOTI = "COMMENTNOTI" + private const val KEY_HOW_TO_LEVELUP = "HOWTOLEVELUP" + private const val MY_FEED_SCREEN = "MyFeedFragment" } } diff --git a/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt index 110b47f4..8ad14676 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt @@ -58,7 +58,7 @@ class SplashActivity : BindingActivity(R.layout.activity_ if (accessToken.isNullOrBlank()) { navigateTo() } else { - navigateTo() + navigateToMainScreen() } } @@ -69,7 +69,20 @@ class SplashActivity : BindingActivity(R.layout.activity_ } } + private fun navigateToMainScreen() { + Intent(this, MainActivity::class.java).apply { + if(intent.extras != null){ + putExtra(KEY_NOTI_TYPE,intent.getStringExtra(KEY_NOTI_TYPE)) + putExtra(KEY_FEED_ID,intent.getStringExtra(KEY_FEED_ID)) + } + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(this) + } + } + companion object { + private const val KEY_FEED_ID = "feedId" + private const val KEY_NOTI_TYPE = "notiType" private const val DELAY_TIME = 1500L } } From 01d7885b3d49d270e07e758235d80fdaaa127eec Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 03:04:33 +0900 Subject: [PATCH 27/40] =?UTF-8?q?[feat]=20=EC=95=B1=EC=9D=B4=20foreground?= =?UTF-8?q?=EC=9D=B8=EC=A7=80=20=ED=8C=90=EB=B3=84=20=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/go/sopt/winey/WineyApplication.kt | 25 +++++++++++++++++++ .../configuration/WineyMessagingService.kt | 4 +-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/WineyApplication.kt b/app/src/main/java/org/go/sopt/winey/WineyApplication.kt index 4c918592..ae0341eb 100644 --- a/app/src/main/java/org/go/sopt/winey/WineyApplication.kt +++ b/app/src/main/java/org/go/sopt/winey/WineyApplication.kt @@ -1,6 +1,7 @@ package org.go.sopt.winey import android.app.Application +import android.os.Bundle import androidx.appcompat.app.AppCompatDelegate import com.kakao.sdk.common.KakaoSdk import dagger.hilt.android.HiltAndroidApp @@ -14,6 +15,26 @@ class WineyApplication : Application() { setupTimber() setupKakaoSdk() preventDarkMode() + + registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks { + override fun onActivityCreated(activity: android.app.Activity, savedInstanceState: Bundle?) {} + + override fun onActivityStarted(activity: android.app.Activity) {} + + override fun onActivityResumed(activity: android.app.Activity) { + isAppInForeground = true + } + + override fun onActivityPaused(activity: android.app.Activity) { + isAppInForeground = false + } + + override fun onActivityStopped(activity: android.app.Activity) {} + + override fun onActivitySaveInstanceState(activity: android.app.Activity, outState: Bundle) {} + + override fun onActivityDestroyed(activity: android.app.Activity) {} + }) } private fun setupTimber() { @@ -27,4 +48,8 @@ class WineyApplication : Application() { private fun preventDarkMode() { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) } + + companion object { + var isAppInForeground = false + } } diff --git a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt index b9650d6e..e99d2521 100644 --- a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt +++ b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt @@ -15,6 +15,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.go.sopt.winey.R +import org.go.sopt.winey.WineyApplication import org.go.sopt.winey.domain.repository.DataStoreRepository import org.go.sopt.winey.presentation.splash.SplashActivity import javax.inject.Inject @@ -33,8 +34,7 @@ class WineyMessagingService : FirebaseMessagingService() { override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) - - if (remoteMessage.data.isNotEmpty()) { + if (remoteMessage.data.isNotEmpty() && !WineyApplication.isAppInForeground) { sendNotification(remoteMessage) } } From 39ba5d9d4d91342728240b5ef2e1a041c24c1889 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 03:05:02 +0900 Subject: [PATCH 28/40] =?UTF-8?q?[chore]=20=ED=86=A0=ED=81=B0=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/go/sopt/winey/data/interceptor/AuthInterceptor.kt | 6 +++++- .../org/go/sopt/winey/presentation/main/MainViewModel.kt | 2 +- .../sopt/winey/presentation/main/feed/WineyFeedFragment.kt | 4 ++++ .../sopt/winey/presentation/main/mypage/MyPageFragment.kt | 5 +++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/data/interceptor/AuthInterceptor.kt b/app/src/main/java/org/go/sopt/winey/data/interceptor/AuthInterceptor.kt index 33b89061..53382aaf 100644 --- a/app/src/main/java/org/go/sopt/winey/data/interceptor/AuthInterceptor.kt +++ b/app/src/main/java/org/go/sopt/winey/data/interceptor/AuthInterceptor.kt @@ -66,7 +66,11 @@ class AuthInterceptor @Inject constructor( dataStoreRepository.saveAccessToken(accessToken, refreshToken) } - private fun handleTokenExpired(chain: Interceptor.Chain, originalRequest: Request, headerRequest: Request): Response { + private fun handleTokenExpired( + chain: Interceptor.Chain, + originalRequest: Request, + headerRequest: Request + ): Response { val refreshTokenRequest = originalRequest.newBuilder().post("".toRequestBody()) .url("$AUTH_BASE_URL/auth/token") .addHeader(REFRESH_TOKEN, runBlocking(Dispatchers.IO) { getRefreshToken() }) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt index 6f005aa8..416ea195 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt @@ -117,7 +117,7 @@ class MainViewModel @Inject constructor( fun patchFcmToken() { viewModelScope.launch { val token = dataStoreRepository.getDeviceToken().first() - if(token.isNullOrBlank()){ + if (token.isNullOrBlank()) { return@launch } authRepository.patchFcmToken(token) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt index 8acd300f..0a77c65b 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt @@ -33,6 +33,7 @@ import org.go.sopt.winey.presentation.main.feed.upload.UploadActivity import org.go.sopt.winey.presentation.main.mypage.MyPageFragment import org.go.sopt.winey.presentation.main.notification.NotificationActivity import org.go.sopt.winey.presentation.model.WineyDialogLabel +import org.go.sopt.winey.presentation.onboarding.login.LoginActivity import org.go.sopt.winey.util.amplitude.AmplitudeUtils import org.go.sopt.winey.util.amplitude.type.EventType import org.go.sopt.winey.util.amplitude.type.EventType.TYPE_CLICK_FEED_ITEM @@ -335,6 +336,9 @@ class WineyFeedFragment : } is UiState.Failure -> { + val intent = Intent(requireActivity(), LoginActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(intent) snackBar(binding.root) { state.msg } } diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt index 7ded1049..5aa3aab8 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt @@ -27,6 +27,7 @@ import org.go.sopt.winey.presentation.main.notification.NotificationActivity import org.go.sopt.winey.presentation.model.WineyDialogLabel import org.go.sopt.winey.presentation.nickname.NicknameActivity import org.go.sopt.winey.presentation.onboarding.guide.GuideActivity +import org.go.sopt.winey.presentation.onboarding.login.LoginActivity import org.go.sopt.winey.util.amplitude.AmplitudeUtils import org.go.sopt.winey.util.binding.BindingFragment import org.go.sopt.winey.util.fragment.WineyDialogFragment @@ -36,6 +37,7 @@ import org.go.sopt.winey.util.fragment.viewLifeCycle import org.go.sopt.winey.util.fragment.viewLifeCycleScope import org.go.sopt.winey.util.view.UiState import org.go.sopt.winey.util.view.setOnSingleClickListener +import retrofit2.HttpException import javax.inject.Inject @AndroidEntryPoint @@ -297,6 +299,9 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ } is UiState.Failure -> { + val intent = Intent(requireActivity(), LoginActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(intent) snackBar(binding.root) { state.msg } } From bc1835a257c98356dc33d265dc3ecbf61144f80e Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 03:07:49 +0900 Subject: [PATCH 29/40] [chore] ktlintformat --- .../go/sopt/winey/configuration/WineyMessagingService.kt | 2 +- .../go/sopt/winey/domain/repository/DataStoreRepository.kt | 2 +- .../org/go/sopt/winey/presentation/main/MainActivity.kt | 2 +- .../sopt/winey/presentation/main/mypage/MyPageFragment.kt | 1 - .../sopt/winey/presentation/main/mypage/MyPageViewModel.kt | 2 +- .../org/go/sopt/winey/presentation/splash/SplashActivity.kt | 6 +++--- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt index e99d2521..8f547824 100644 --- a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt +++ b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt @@ -50,7 +50,7 @@ class WineyMessagingService : FirebaseMessagingService() { this, uniId, intent, - PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE, + PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE ) val channelId = CHANNEL_ID diff --git a/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt b/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt index 47cd6108..444578e3 100644 --- a/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt +++ b/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt @@ -19,7 +19,7 @@ interface DataStoreRepository { suspend fun getRefreshToken(): Flow - suspend fun getDeviceToken():Flow + suspend fun getDeviceToken(): Flow suspend fun getStringValue(key: Preferences.Key): Flow diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt index 11e78cba..be331929 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt @@ -32,7 +32,7 @@ class MainActivity : BindingActivity(R.layout.activity_main private val isDeleteSuccess by lazy { intent.extras?.getBoolean(EXTRA_DELETE_KEY, false) } private val isReportSuccess by lazy { intent.extras?.getBoolean(EXTRA_REPORT_KEY, false) } private val prevScreenName by lazy { intent.extras?.getString(KEY_PREV_SCREEN, "") } - private val notiType by lazy { intent.extras?.getString(KEY_NOTI_TYPE,"") } + private val notiType by lazy { intent.extras?.getString(KEY_NOTI_TYPE, "") } private val feedId by lazy { intent.extras?.getString(KEY_FEED_ID) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt index 5aa3aab8..7b2ae072 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt @@ -37,7 +37,6 @@ import org.go.sopt.winey.util.fragment.viewLifeCycle import org.go.sopt.winey.util.fragment.viewLifeCycleScope import org.go.sopt.winey.util.view.UiState import org.go.sopt.winey.util.view.setOnSingleClickListener -import retrofit2.HttpException import javax.inject.Inject @AndroidEntryPoint diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt index ed64c4ae..6346e006 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt @@ -52,7 +52,7 @@ class MyPageViewModel @Inject constructor( Timber.d("SUCCESS PATCH ALLOWED NOTI") _patchAllowedNotificationState.value = UiState.Success(response) } - .onFailure {t -> + .onFailure { t -> _patchAllowedNotificationState.value = UiState.Failure(t.message.toString()) if (t is HttpException) { diff --git a/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt index 8ad14676..904391a3 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt @@ -71,9 +71,9 @@ class SplashActivity : BindingActivity(R.layout.activity_ private fun navigateToMainScreen() { Intent(this, MainActivity::class.java).apply { - if(intent.extras != null){ - putExtra(KEY_NOTI_TYPE,intent.getStringExtra(KEY_NOTI_TYPE)) - putExtra(KEY_FEED_ID,intent.getStringExtra(KEY_FEED_ID)) + if (intent.extras != null) { + putExtra(KEY_NOTI_TYPE, intent.getStringExtra(KEY_NOTI_TYPE)) + putExtra(KEY_FEED_ID, intent.getStringExtra(KEY_FEED_ID)) } addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(this) From 4235bb275550ebfc4b481f1e7e285707f1517995 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 03:28:01 +0900 Subject: [PATCH 30/40] =?UTF-8?q?[chore]=20string=20=EB=A6=AC=EC=86=8C?= =?UTF-8?q?=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/fragment_my_page.xml | 2 +- app/src/main/res/values/strings.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/fragment_my_page.xml b/app/src/main/res/layout/fragment_my_page.xml index 53f5283c..b893bb08 100644 --- a/app/src/main/res/layout/fragment_my_page.xml +++ b/app/src/main/res/layout/fragment_my_page.xml @@ -369,7 +369,7 @@ android:layout_height="wrap_content" android:layout_marginStart="23dp" android:layout_marginTop="17dp" - android:text="알림설정" + android:text="@string/mypage_noti_agree" android:textAppearance="@style/TextAppearance.WINEY.body_m_16" android:textColor="@color/gray_700" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a1065fed..12c32f7f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -88,6 +88,7 @@ 닫기 1:1 문의 이용약관 + 알림설정 탈퇴하기 로그아웃 From 643ef55f1ac9bcb6c0c0101f0b779cdca461fe2a Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 03:48:10 +0900 Subject: [PATCH 31/40] =?UTF-8?q?[chore]=20prchecker=20google=20service.js?= =?UTF-8?q?on=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/pr_checker.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/pr_checker.yml b/.github/workflows/pr_checker.yml index 4b163a82..96d198a4 100644 --- a/.github/workflows/pr_checker.yml +++ b/.github/workflows/pr_checker.yml @@ -57,6 +57,11 @@ jobs: echo keyPassword=$KEY_PASSWORD >> ./local.properties echo storePassword=$STORE_PASSWORD >> ./local.properties + - name: Create Google Services JSON File + env: + GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICE_JSON }} + run: echo $GOOGLE_SERVICE_JSON | base64 -di > ./app/google-services.json + - name: Build debug APK run: ./gradlew assembleDebug --stacktrace From a9c5f7ac888d3a7b7e372579f5f800430e4f2398 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 04:06:12 +0900 Subject: [PATCH 32/40] =?UTF-8?q?[chore]=20pr=20checker=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/pr_checker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_checker.yml b/.github/workflows/pr_checker.yml index 96d198a4..34e0a161 100644 --- a/.github/workflows/pr_checker.yml +++ b/.github/workflows/pr_checker.yml @@ -60,7 +60,7 @@ jobs: - name: Create Google Services JSON File env: GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICE_JSON }} - run: echo $GOOGLE_SERVICE_JSON | base64 -di > ./app/google-services.json + run: echo $GOOGLE_SERVICE_JSON | base64 --decode > ./app/google-services.json - name: Build debug APK run: ./gradlew assembleDebug --stacktrace From c8ee5706e5965a37c94c5f236ed634c0f98ef7ae Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Wed, 6 Dec 2023 04:25:53 +0900 Subject: [PATCH 33/40] [chore] prchecker --- .github/workflows/pr_checker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr_checker.yml b/.github/workflows/pr_checker.yml index 34e0a161..f8f6b628 100644 --- a/.github/workflows/pr_checker.yml +++ b/.github/workflows/pr_checker.yml @@ -59,8 +59,8 @@ jobs: - name: Create Google Services JSON File env: - GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICE_JSON }} - run: echo $GOOGLE_SERVICE_JSON | base64 --decode > ./app/google-services.json + GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }} + run: echo $GOOGLE_SERVICES_JSON > ./app/google-services.json - name: Build debug APK run: ./gradlew assembleDebug --stacktrace From a4312b098b3a480b864a6dad65834b09515a1c2a Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Thu, 21 Dec 2023 14:17:06 +0900 Subject: [PATCH 34/40] =?UTF-8?q?[refactor]=20activitylifecyclecallbacks?= =?UTF-8?q?=20=ED=81=B4=EB=9E=98=EC=8A=A4=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../go/sopt/winey/ActivityLifecycleHandler.kt | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 app/src/main/java/org/go/sopt/winey/ActivityLifecycleHandler.kt diff --git a/app/src/main/java/org/go/sopt/winey/ActivityLifecycleHandler.kt b/app/src/main/java/org/go/sopt/winey/ActivityLifecycleHandler.kt new file mode 100644 index 00000000..562cab42 --- /dev/null +++ b/app/src/main/java/org/go/sopt/winey/ActivityLifecycleHandler.kt @@ -0,0 +1,35 @@ +package org.go.sopt.winey + +import android.app.Activity +import android.app.Application +import android.os.Bundle + +class ActivityLifecycleHandler(private val application: Application) : + Application.ActivityLifecycleCallbacks { + override fun onActivityCreated(p0: Activity, p1: Bundle?) { + } + + override fun onActivityStarted(p0: Activity) { + } + + override fun onActivityResumed(p0: Activity) { + isAppInForeground = true + } + + override fun onActivityPaused(p0: Activity) { + isAppInForeground = false + } + + override fun onActivityStopped(p0: Activity) { + } + + override fun onActivitySaveInstanceState(p0: Activity, p1: Bundle) { + } + + override fun onActivityDestroyed(p0: Activity) { + } + + companion object { + var isAppInForeground = false + } +} From c098203d9398b29919b43668c8a75ab22b63ef15 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Thu, 21 Dec 2023 14:17:54 +0900 Subject: [PATCH 35/40] =?UTF-8?q?[refactor]=20wineymessagingservice=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=84=B8=EB=B6=84=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuration/WineyMessagingService.kt | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt index 8f547824..7c8915a6 100644 --- a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt +++ b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt @@ -6,6 +6,7 @@ import android.app.PendingIntent import android.content.Context import android.content.Intent import android.media.RingtoneManager +import android.net.Uri import android.os.Build import androidx.core.app.NotificationCompat import com.google.firebase.messaging.FirebaseMessagingService @@ -14,8 +15,8 @@ import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import org.go.sopt.winey.ActivityLifecycleHandler import org.go.sopt.winey.R -import org.go.sopt.winey.WineyApplication import org.go.sopt.winey.domain.repository.DataStoreRepository import org.go.sopt.winey.presentation.splash.SplashActivity import javax.inject.Inject @@ -34,30 +35,40 @@ class WineyMessagingService : FirebaseMessagingService() { override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) - if (remoteMessage.data.isNotEmpty() && !WineyApplication.isAppInForeground) { + if (remoteMessage.data.isNotEmpty() && !ActivityLifecycleHandler.isAppInForeground) { sendNotification(remoteMessage) } } - private fun sendNotification(remoteMessage: RemoteMessage) { - val uniId: Int = (System.currentTimeMillis() / 7).toInt() + private fun createNotificationIntent(remoteMessage: RemoteMessage): Intent { + return Intent(this, SplashActivity::class.java).apply { + putExtra(KEY_NOTI_TYPE, remoteMessage.data[KEY_NOTI_TYPE]) + putExtra(KEY_FEED_ID, remoteMessage.data[KEY_FEED_ID]) + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + } + } - val intent = Intent(this, SplashActivity::class.java) - intent.putExtra(KEY_NOTI_TYPE, remoteMessage.data[KEY_NOTI_TYPE]) - intent.putExtra(KEY_FEED_ID, remoteMessage.data[KEY_FEED_ID]) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - val pendingIntent = PendingIntent.getActivity( + private fun createPendingIntent(intent: Intent, uniqueIdentifier: Int): PendingIntent { + return PendingIntent.getActivity( this, - uniId, + uniqueIdentifier, intent, PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE ) + } + + private fun getSoundUri(): Uri { + return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) + } - val channelId = CHANNEL_ID + private fun generateUniqueIdentifier(): Int { + return (System.currentTimeMillis() / 7).toInt() + } - val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) + private fun createAndShowNotification(remoteMessage: RemoteMessage, uniqueIdentifier: Int, pendingIntent: PendingIntent) { + val soundUri = getSoundUri() - val notificationBuilder = NotificationCompat.Builder(this, channelId) + val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(remoteMessage.data[KEY_TITLE]) .setContentText(remoteMessage.data[KEY_MESSAGE]) @@ -65,25 +76,29 @@ class WineyMessagingService : FirebaseMessagingService() { .setSound(soundUri) .setContentIntent(pendingIntent) - val notificationManager = - getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val channel = - NotificationChannel(channelId, NOTICE, NotificationManager.IMPORTANCE_DEFAULT) + val channel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT) notificationManager.createNotificationChannel(channel) } - notificationManager.notify(uniId, notificationBuilder.build()) + notificationManager.notify(uniqueIdentifier, notificationBuilder.build()) + } + private fun sendNotification(remoteMessage: RemoteMessage) { + val uniqueIdentifier = generateUniqueIdentifier() + val intent = createNotificationIntent(remoteMessage) + val pendingIntent = createPendingIntent(intent, uniqueIdentifier) + + createAndShowNotification(remoteMessage, uniqueIdentifier, pendingIntent) } companion object { - private const val TAG = "FirebaseService" private const val KEY_FEED_ID = "feedId" private const val KEY_NOTI_TYPE = "notiType" private const val KEY_TITLE = "title" private const val KEY_MESSAGE = "message" - private const val NOTICE = "Notice" + private const val CHANNEL_NAME = "Notice" private const val CHANNEL_ID = "channel" } } From a66700ff72174cd241344b561fa63da388ebc3a1 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Thu, 21 Dec 2023 14:18:26 +0900 Subject: [PATCH 36/40] =?UTF-8?q?[refactor]=20wineyApplication=20=EC=BD=9C?= =?UTF-8?q?=EB=B0=B1=20=ED=81=B4=EB=9E=98=EC=8A=A4=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/go/sopt/winey/WineyApplication.kt | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/WineyApplication.kt b/app/src/main/java/org/go/sopt/winey/WineyApplication.kt index ae0341eb..b16dbd3d 100644 --- a/app/src/main/java/org/go/sopt/winey/WineyApplication.kt +++ b/app/src/main/java/org/go/sopt/winey/WineyApplication.kt @@ -1,7 +1,6 @@ package org.go.sopt.winey import android.app.Application -import android.os.Bundle import androidx.appcompat.app.AppCompatDelegate import com.kakao.sdk.common.KakaoSdk import dagger.hilt.android.HiltAndroidApp @@ -15,26 +14,7 @@ class WineyApplication : Application() { setupTimber() setupKakaoSdk() preventDarkMode() - - registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks { - override fun onActivityCreated(activity: android.app.Activity, savedInstanceState: Bundle?) {} - - override fun onActivityStarted(activity: android.app.Activity) {} - - override fun onActivityResumed(activity: android.app.Activity) { - isAppInForeground = true - } - - override fun onActivityPaused(activity: android.app.Activity) { - isAppInForeground = false - } - - override fun onActivityStopped(activity: android.app.Activity) {} - - override fun onActivitySaveInstanceState(activity: android.app.Activity, outState: Bundle) {} - - override fun onActivityDestroyed(activity: android.app.Activity) {} - }) + registerActivityLifecycleCallbacks(ActivityLifecycleHandler(this)) } private fun setupTimber() { @@ -48,8 +28,4 @@ class WineyApplication : Application() { private fun preventDarkMode() { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) } - - companion object { - var isAppInForeground = false - } } From dd0c643848075e29c9303c978717ae0629a9ec01 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Thu, 21 Dec 2023 14:18:44 +0900 Subject: [PATCH 37/40] =?UTF-8?q?[feat]=20notificationtype=20enum=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../winey/presentation/model/NotificationType.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 app/src/main/java/org/go/sopt/winey/presentation/model/NotificationType.kt diff --git a/app/src/main/java/org/go/sopt/winey/presentation/model/NotificationType.kt b/app/src/main/java/org/go/sopt/winey/presentation/model/NotificationType.kt new file mode 100644 index 00000000..d80ff00d --- /dev/null +++ b/app/src/main/java/org/go/sopt/winey/presentation/model/NotificationType.kt @@ -0,0 +1,14 @@ +package org.go.sopt.winey.presentation.model + +enum class NotificationType(val key: String) { + RANK_UP_TO_2("RANKUPTO2"), + RANK_UP_TO_3("RANKUPTO3"), + RANK_UP_TO_4("RANKUPTO4"), + RANK_DOWN_TO_1("DELETERANKDOWNTO1"), + RANK_DOWN_TO_2("DELETERANKDOWNTO2"), + RANK_DOWN_TO_3("DELETERANKDOWNTO3"), + GOAL_FAILED("GOALFAILED"), + LIKE_NOTIFICATION("LIKENOTI"), + COMMENT_NOTIFICATION("COMMENTNOTI"), + HOW_TO_LEVEL_UP("HOWTOLEVELUP") +} From bc88e5fc6f20653f08ed08153eaa37357ecb60bf Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Thu, 21 Dec 2023 14:19:43 +0900 Subject: [PATCH 38/40] =?UTF-8?q?[mod]=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../winey/presentation/main/MainActivity.kt | 38 +++++++------------ .../winey/presentation/main/MainViewModel.kt | 7 ++-- .../main/feed/WineyFeedFragment.kt | 4 -- .../main/mypage/MyPageFragment.kt | 28 ++++++-------- .../main/res/drawable/ic_mypage_switchoff.xml | 12 ------ .../main/res/drawable/ic_mypage_switchon.xml | 12 ------ app/src/main/res/layout/fragment_my_page.xml | 4 +- ...xml => mypage_noti_agree_motion_scene.xml} | 0 8 files changed, 30 insertions(+), 75 deletions(-) delete mode 100644 app/src/main/res/drawable/ic_mypage_switchoff.xml delete mode 100644 app/src/main/res/drawable/ic_mypage_switchon.xml rename app/src/main/res/xml/{fragment_my_page_xml_cl_mypage_agree_scene.xml => mypage_noti_agree_motion_scene.xml} (100%) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt index ace92cea..eb2d417d 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt @@ -18,6 +18,7 @@ import org.go.sopt.winey.presentation.main.feed.detail.DetailActivity import org.go.sopt.winey.presentation.main.mypage.MyPageFragment import org.go.sopt.winey.presentation.main.mypage.MypageHelpActivity import org.go.sopt.winey.presentation.main.recommend.RecommendFragment +import org.go.sopt.winey.presentation.model.NotificationType import org.go.sopt.winey.presentation.onboarding.login.LoginActivity import org.go.sopt.winey.util.binding.BindingActivity import org.go.sopt.winey.util.context.snackBar @@ -51,18 +52,22 @@ class MainActivity : BindingActivity(R.layout.activity_main } private fun initNotiTypeHandler() { - when (notiType) { - KEY_RANKUP_TO_2, KEY_RANKUP_TO_3, KEY_RANKUP_TO_4 -> navigateToMyPageWithBundle(KEY_FROM_NOTI, true) - KEY_RANKDOWN_TO_1, KEY_RANKDOWN_TO_2, KEY_RANKDOWN_TO_3 -> navigateToMyPageWithBundle( + val notificationType = NotificationType.values().find { it.key == notiType } + when (notificationType) { + NotificationType.RANK_UP_TO_2, NotificationType.RANK_UP_TO_3, NotificationType.RANK_UP_TO_4 -> navigateToMyPageWithBundle( KEY_FROM_NOTI, true ) - KEY_GOAL_FAILED -> navigateToMyPageWithBundle(KEY_FROM_NOTI, true) - KEY_LIKE_NOTI -> navigateToDetail(feedId?.toInt()) - KEY_COMMENT_NOTI -> navigateToDetail(feedId?.toInt()) - KEY_HOW_TO_LEVELUP -> navigateToLevelupHelp() - else -> null + NotificationType.RANK_DOWN_TO_1, NotificationType.RANK_DOWN_TO_2, NotificationType.RANK_DOWN_TO_3 -> navigateToMyPageWithBundle( + KEY_FROM_NOTI, + true + ) + + NotificationType.GOAL_FAILED -> navigateToMyPageWithBundle(KEY_FROM_NOTI, true) + NotificationType.LIKE_NOTIFICATION -> navigateToDetail(feedId?.toInt()) + NotificationType.COMMENT_NOTIFICATION -> navigateToDetail(feedId?.toInt()) + else -> navigateToLevelupHelp() } } @@ -182,23 +187,6 @@ class MainActivity : BindingActivity(R.layout.activity_main private const val KEY_TO_MYFEED = "toMyFeed" private const val KEY_TO_MYPAGE = "navigateMypage" - private const val KEY_RANKUP_TO_2 = "RANKUPTO2" - private const val KEY_RANKUP_TO_3 = "RANKUPTO3" - private const val KEY_RANKUP_TO_4 = "RANKUPTO4" - - private const val KEY_RANKDOWN_TO_1 = "DELETERANKDOWNTO1" - private const val KEY_RANKDOWN_TO_2 = "DELETERANKDOWNTO2" - private const val KEY_RANKDOWN_TO_3 = "DELETERANKDOWNTO3" - - private const val KEY_GOAL_FAILED = "GOALFAILED" - private const val KEY_LIKE_NOTI = "LIKENOTI" - private const val KEY_COMMENT_NOTI = "COMMENTNOTI" - private const val KEY_HOW_TO_LEVELUP = "HOWTOLEVELUP" - - private const val MY_FEED_SCREEN = "MyFeedFragment" - private const val KEY_FEED_UPLOAD = "upload" - private const val KEY_FEED_DELETE = "delete" - private const val KEY_PREV_SCREEN_NAME = "PREV_SCREEN_NAME" private const val VAL_MY_FEED_SCREEN = "MyFeedFragment" } } diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt index 416ea195..f274086f 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt @@ -48,7 +48,7 @@ class MainViewModel @Inject constructor( .onFailure { t -> if (t is HttpException) { Timber.e("HTTP 실패 ${t.code()}") - if (t.code() == CODE_TOKEN_EXPIRED) { + if (t.code() == CODE_TOKEN_EXPIRED || t.code() == CODE_INVALID_USER) { postLogout() } } @@ -117,9 +117,7 @@ class MainViewModel @Inject constructor( fun patchFcmToken() { viewModelScope.launch { val token = dataStoreRepository.getDeviceToken().first() - if (token.isNullOrBlank()) { - return@launch - } + if (token.isNullOrBlank()) return@launch authRepository.patchFcmToken(token) .onSuccess { Timber.e("디바이스 토큰 보내기 성공") @@ -135,5 +133,6 @@ class MainViewModel @Inject constructor( companion object { private const val CODE_TOKEN_EXPIRED = 401 + private const val CODE_INVALID_USER = 404 } } diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt index 2a810113..0e152ae6 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt @@ -33,7 +33,6 @@ import org.go.sopt.winey.presentation.main.feed.upload.UploadActivity import org.go.sopt.winey.presentation.main.mypage.MyPageFragment import org.go.sopt.winey.presentation.main.notification.NotificationActivity import org.go.sopt.winey.presentation.model.WineyDialogLabel -import org.go.sopt.winey.presentation.onboarding.login.LoginActivity import org.go.sopt.winey.util.activity.showReportGoogleForm import org.go.sopt.winey.util.amplitude.AmplitudeUtils import org.go.sopt.winey.util.amplitude.type.EventType @@ -333,9 +332,6 @@ class WineyFeedFragment : } is UiState.Failure -> { - val intent = Intent(requireActivity(), LoginActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) - startActivity(intent) snackBar(binding.root) { state.msg } } diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt index e11e24ac..a5dce48f 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt @@ -27,7 +27,6 @@ import org.go.sopt.winey.presentation.main.notification.NotificationActivity import org.go.sopt.winey.presentation.model.WineyDialogLabel import org.go.sopt.winey.presentation.nickname.NicknameActivity import org.go.sopt.winey.presentation.onboarding.guide.GuideActivity -import org.go.sopt.winey.presentation.onboarding.login.LoginActivity import org.go.sopt.winey.util.amplitude.AmplitudeUtils import org.go.sopt.winey.util.binding.BindingFragment import org.go.sopt.winey.util.fragment.WineyDialogFragment @@ -110,26 +109,26 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ when (isAllowed) { true -> { binding.ivMypageAgree.transitionToStart() - lifecycleScope.launch { - val data = dataStoreRepository.getUserInfo().first() - val newData = data?.copy(fcmIsAllowed = false) - dataStoreRepository.saveUserInfo(newData) - } + patchUserInfo() } false -> { binding.ivMypageAgree.transitionToEnd() - lifecycleScope.launch { - val data = dataStoreRepository.getUserInfo().first() - val newData = data?.copy(fcmIsAllowed = true) - dataStoreRepository.saveUserInfo(newData) - } + patchUserInfo() } } myPageViewModel.patchAllowedNotification(isAllowed) } } + private fun patchUserInfo() { + lifecycleScope.launch { + val data = dataStoreRepository.getUserInfo().first() + val newData = data?.copy(fcmIsAllowed = false) + dataStoreRepository.saveUserInfo(newData) + } + } + // 닉네임 액티비티 갔다가 다시 돌아왔을 때 유저 데이터 갱신하도록 override fun onStart() { super.onStart() @@ -298,9 +297,6 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ } is UiState.Failure -> { - val intent = Intent(requireActivity(), LoginActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) - startActivity(intent) snackBar(binding.root) { state.msg } } @@ -313,7 +309,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ binding.data = data updateTargetInfo(data) updateUserLevel(data) - updateSwitchState(data) + updateNotificationAllowSwitchState(data) } private fun updateTargetInfo(data: User) { @@ -356,7 +352,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ } } - private fun updateSwitchState(data: User) { + private fun updateNotificationAllowSwitchState(data: User) { when (data.fcmIsAllowed) { true -> { binding.ivMypageAgree.transitionToEnd() diff --git a/app/src/main/res/drawable/ic_mypage_switchoff.xml b/app/src/main/res/drawable/ic_mypage_switchoff.xml deleted file mode 100644 index 3d1fef8f..00000000 --- a/app/src/main/res/drawable/ic_mypage_switchoff.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_mypage_switchon.xml b/app/src/main/res/drawable/ic_mypage_switchon.xml deleted file mode 100644 index 1c061691..00000000 --- a/app/src/main/res/drawable/ic_mypage_switchon.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/app/src/main/res/layout/fragment_my_page.xml b/app/src/main/res/layout/fragment_my_page.xml index b893bb08..3edcd7f9 100644 --- a/app/src/main/res/layout/fragment_my_page.xml +++ b/app/src/main/res/layout/fragment_my_page.xml @@ -359,7 +359,7 @@ android:id="@+id/cl_mypage_agree" android:layout_width="match_parent" android:layout_height="wrap_content" - app:layoutDescription="@xml/fragment_my_page_xml_cl_mypage_agree_scene" + app:layoutDescription="@xml/mypage_noti_agree_motion_scene" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/v_mypage_line6"> @@ -383,7 +383,7 @@ android:layout_marginTop="15dp" android:layout_marginBottom="16dp" android:background="@android:color/transparent" - app:layoutDescription="@xml/fragment_my_page_xml_cl_mypage_agree_scene" + app:layoutDescription="@xml/mypage_noti_agree_motion_scene" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" > diff --git a/app/src/main/res/xml/fragment_my_page_xml_cl_mypage_agree_scene.xml b/app/src/main/res/xml/mypage_noti_agree_motion_scene.xml similarity index 100% rename from app/src/main/res/xml/fragment_my_page_xml_cl_mypage_agree_scene.xml rename to app/src/main/res/xml/mypage_noti_agree_motion_scene.xml From d119f8af02b10a389b6f05e3a52cf7aad28a1367 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Thu, 28 Dec 2023 03:55:08 +0900 Subject: [PATCH 39/40] =?UTF-8?q?[mod]=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../winey/configuration/WineyMessagingService.kt | 10 +++++++--- .../sopt/winey/presentation/main/MainActivity.kt | 16 ++++++---------- .../presentation/main/mypage/MyPageFragment.kt | 3 +-- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt index 7c8915a6..fdd23771 100644 --- a/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt +++ b/app/src/main/java/org/go/sopt/winey/configuration/WineyMessagingService.kt @@ -65,17 +65,19 @@ class WineyMessagingService : FirebaseMessagingService() { return (System.currentTimeMillis() / 7).toInt() } - private fun createAndShowNotification(remoteMessage: RemoteMessage, uniqueIdentifier: Int, pendingIntent: PendingIntent) { + private fun createNotificationBuilder(remoteMessage: RemoteMessage, pendingIntent: PendingIntent): NotificationCompat.Builder { val soundUri = getSoundUri() - val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) + return NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(remoteMessage.data[KEY_TITLE]) .setContentText(remoteMessage.data[KEY_MESSAGE]) .setAutoCancel(true) .setSound(soundUri) .setContentIntent(pendingIntent) + } + private fun showNotification(notificationBuilder: NotificationCompat.Builder, uniqueIdentifier: Int) { val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -85,12 +87,14 @@ class WineyMessagingService : FirebaseMessagingService() { notificationManager.notify(uniqueIdentifier, notificationBuilder.build()) } + private fun sendNotification(remoteMessage: RemoteMessage) { val uniqueIdentifier = generateUniqueIdentifier() val intent = createNotificationIntent(remoteMessage) val pendingIntent = createPendingIntent(intent, uniqueIdentifier) + val notification = createNotificationBuilder(remoteMessage, pendingIntent) - createAndShowNotification(remoteMessage, uniqueIdentifier, pendingIntent) + showNotification(notification, uniqueIdentifier) } companion object { diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt index eb2d417d..52aadaf5 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt @@ -54,19 +54,15 @@ class MainActivity : BindingActivity(R.layout.activity_main private fun initNotiTypeHandler() { val notificationType = NotificationType.values().find { it.key == notiType } when (notificationType) { - NotificationType.RANK_UP_TO_2, NotificationType.RANK_UP_TO_3, NotificationType.RANK_UP_TO_4 -> navigateToMyPageWithBundle( + NotificationType.RANK_UP_TO_2, NotificationType.RANK_UP_TO_3, + NotificationType.RANK_UP_TO_4, NotificationType.RANK_DOWN_TO_1, + NotificationType.RANK_DOWN_TO_2, NotificationType.RANK_DOWN_TO_3, + NotificationType.GOAL_FAILED-> navigateToMyPageWithBundle( KEY_FROM_NOTI, true ) - - NotificationType.RANK_DOWN_TO_1, NotificationType.RANK_DOWN_TO_2, NotificationType.RANK_DOWN_TO_3 -> navigateToMyPageWithBundle( - KEY_FROM_NOTI, - true - ) - - NotificationType.GOAL_FAILED -> navigateToMyPageWithBundle(KEY_FROM_NOTI, true) - NotificationType.LIKE_NOTIFICATION -> navigateToDetail(feedId?.toInt()) - NotificationType.COMMENT_NOTIFICATION -> navigateToDetail(feedId?.toInt()) + NotificationType.LIKE_NOTIFICATION, NotificationType.COMMENT_NOTIFICATION + -> navigateToDetail(feedId?.toInt()) else -> navigateToLevelupHelp() } } diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt index a5dce48f..ed5253a6 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt @@ -109,14 +109,13 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ when (isAllowed) { true -> { binding.ivMypageAgree.transitionToStart() - patchUserInfo() } false -> { binding.ivMypageAgree.transitionToEnd() - patchUserInfo() } } + patchUserInfo() myPageViewModel.patchAllowedNotification(isAllowed) } } From ff8ba9136d9bb8317a672949c6f6e96d8a73f0a7 Mon Sep 17 00:00:00 2001 From: Sangwook123 Date: Thu, 28 Dec 2023 03:58:39 +0900 Subject: [PATCH 40/40] [chore] ktlint --- .../java/org/go/sopt/winey/presentation/main/MainActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt index 52aadaf5..81e180d9 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/MainActivity.kt @@ -57,7 +57,7 @@ class MainActivity : BindingActivity(R.layout.activity_main NotificationType.RANK_UP_TO_2, NotificationType.RANK_UP_TO_3, NotificationType.RANK_UP_TO_4, NotificationType.RANK_DOWN_TO_1, NotificationType.RANK_DOWN_TO_2, NotificationType.RANK_DOWN_TO_3, - NotificationType.GOAL_FAILED-> navigateToMyPageWithBundle( + NotificationType.GOAL_FAILED -> navigateToMyPageWithBundle( KEY_FROM_NOTI, true )