diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 00000000..b5e7a5b6
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1 @@
+* @Ahn-seokjoo @jaeryo2357 @Sookhee
diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index 797761ab..1a9bf2e8 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -4,7 +4,7 @@ on:
push:
branches: [ "develop" ]
pull_request:
- branches: [ "develop" ]
+ branches: [ "develop", "refactor*", "fix*", "feat*", "feature*", "chore*", "test*" ]
jobs:
build:
diff --git a/.gitignore b/.gitignore
index a876adea..2f22f858 100644
--- a/.gitignore
+++ b/.gitignore
@@ -123,6 +123,7 @@ obj/
.idea/gradle.xml
.idea/jarRepositories.xml
.idea/navEditor.xml
+.idea/codeStyles/Project.xml
# OS-specific files
.DS_Store
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 26d33521..00000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
deleted file mode 100644
index 9f503962..00000000
--- a/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,128 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- xmlns:android
-
- ^$
-
-
-
-
-
-
-
-
- xmlns:.*
-
- ^$
-
-
- BY_NAME
-
-
-
-
-
-
- .*:id
-
- http://schemas.android.com/apk/res/android
-
-
-
-
-
-
-
-
- .*:name
-
- http://schemas.android.com/apk/res/android
-
-
-
-
-
-
-
-
- name
-
- ^$
-
-
-
-
-
-
-
-
- style
-
- ^$
-
-
-
-
-
-
-
-
- .*
-
- ^$
-
-
- BY_NAME
-
-
-
-
-
-
- .*
-
- http://schemas.android.com/apk/res/android
-
-
- ANDROID_ATTRIBUTE_ORDER
-
-
-
-
-
-
- .*
-
- .*
-
-
- BY_NAME
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index 79ee123c..00000000
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 83771bc5..00000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 8fac0723..10f16f58 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -26,8 +26,8 @@ android {
applicationId "com.mashup"
minSdkVersion minVersion
targetSdkVersion targetVersion
- versionCode 20
- versionName "1.1.4"
+ versionCode 21
+ versionName "1.2.0"
testInstrumentationRunner "com.mashup.core.testing.MashUpTestRunner"
vectorDrawables {
@@ -98,6 +98,7 @@ dependencies {
implementation project(":core:datastore")
implementation project(":core:firebase")
implementation project(":feature:setting")
+ implementation project(":feature:danggn")
// ml Kit
implementation "com.google.mlkit:barcode-scanning:$barcodeSacnnerVersion"
@@ -140,4 +141,9 @@ dependencies {
// coroutine test
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutineVersion"
+
+ // flipper
+ implementation "com.facebook.flipper:flipper:$flipperVersion"
+ implementation "com.facebook.soloader:soloader:$soLoaderVersion"
+ implementation "com.facebook.flipper:flipper-network-plugin:$flipperVersion"
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 30a92e8d..75d6841b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -28,6 +28,18 @@
+
+
+
+
+
+
diff --git a/app/src/main/java/com/mashup/MashUpApplication.kt b/app/src/main/java/com/mashup/MashUpApplication.kt
index cfb7483e..d8e18bb5 100644
--- a/app/src/main/java/com/mashup/MashUpApplication.kt
+++ b/app/src/main/java/com/mashup/MashUpApplication.kt
@@ -1,7 +1,25 @@
package com.mashup
import android.app.Application
+import com.facebook.flipper.android.AndroidFlipperClient
+import com.facebook.flipper.android.utils.FlipperUtils
+import com.facebook.flipper.plugins.inspector.DescriptorMapping
+import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin
+import com.facebook.soloader.SoLoader
+import com.mashup.di.NetworkModule
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
-class MashUpApplication : Application()
+class MashUpApplication : Application() {
+ override fun onCreate() {
+ super.onCreate()
+ SoLoader.init(this, false)
+
+ if (BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)) {
+ val client = AndroidFlipperClient.getInstance(this)
+ client.addPlugin(InspectorFlipperPlugin(this, DescriptorMapping.withDefaults()))
+ client.addPlugin(NetworkModule.flipperNetwork)
+ client.start()
+ }
+ }
+}
diff --git a/app/src/main/java/com/mashup/base/BaseActivity.kt b/app/src/main/java/com/mashup/base/BaseActivity.kt
index c39a5780..0adeea57 100644
--- a/app/src/main/java/com/mashup/base/BaseActivity.kt
+++ b/app/src/main/java/com/mashup/base/BaseActivity.kt
@@ -4,6 +4,7 @@ import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.os.bundleOf
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
@@ -12,7 +13,12 @@ import androidx.databinding.ViewDataBinding
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import com.mashup.constant.EXTRA_ACTIVITY_ENTER_TYPE
import com.mashup.constant.EXTRA_ANIMATION
+import com.mashup.core.common.constant.BAD_REQUEST
+import com.mashup.core.common.constant.DISCONNECT_NETWORK
+import com.mashup.core.common.constant.INTERNAL_SERVER_ERROR
+import com.mashup.core.common.constant.UNAUTHORIZED
import com.mashup.core.common.model.NavigationAnimationType
import com.mashup.core.common.utils.ProgressbarUtil
import com.mashup.core.common.utils.ToastUtil
@@ -20,12 +26,9 @@ import com.mashup.core.common.utils.keyboard.RootViewDeferringInsetsCallback
import com.mashup.core.common.widget.CommonDialog
import com.mashup.network.NetworkStatusState
import com.mashup.network.data.NetworkStatusDetector
-import com.mashup.network.errorcode.BAD_REQUEST
-import com.mashup.network.errorcode.DISCONNECT_NETWORK
-import com.mashup.network.errorcode.INTERNAL_SERVER_ERROR
-import com.mashup.network.errorcode.UNAUTHORIZED
import com.mashup.ui.error.NetworkDisconnectActivity
import com.mashup.ui.login.LoginActivity
+import com.mashup.util.AnalyticsManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@@ -179,4 +182,9 @@ abstract class BaseActivity : AppCompatActivity() {
)
}
}
+
+ protected fun sendActivityEnterType(screenName: String) {
+ val type = intent.getStringExtra(EXTRA_ACTIVITY_ENTER_TYPE) ?: return
+ AnalyticsManager.addEvent(screenName, bundleOf("type" to type))
+ }
}
diff --git a/app/src/main/java/com/mashup/base/BaseFragment.kt b/app/src/main/java/com/mashup/base/BaseFragment.kt
index 79eccf8e..18017f9a 100644
--- a/app/src/main/java/com/mashup/base/BaseFragment.kt
+++ b/app/src/main/java/com/mashup/base/BaseFragment.kt
@@ -11,15 +11,15 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import com.mashup.core.common.constant.BAD_REQUEST
+import com.mashup.core.common.constant.DISCONNECT_NETWORK
+import com.mashup.core.common.constant.INTERNAL_SERVER_ERROR
+import com.mashup.core.common.constant.UNAUTHORIZED
import com.mashup.core.common.utils.ProgressbarUtil
import com.mashup.core.common.utils.ToastUtil
import com.mashup.core.common.widget.CommonDialog
import com.mashup.network.NetworkStatusState
import com.mashup.network.data.NetworkStatusDetector
-import com.mashup.network.errorcode.BAD_REQUEST
-import com.mashup.network.errorcode.DISCONNECT_NETWORK
-import com.mashup.network.errorcode.INTERNAL_SERVER_ERROR
-import com.mashup.network.errorcode.UNAUTHORIZED
import com.mashup.ui.error.NetworkDisconnectActivity
import com.mashup.ui.login.LoginActivity
import kotlinx.coroutines.CoroutineScope
diff --git a/app/src/main/java/com/mashup/constant/ExtraConstant.kt b/app/src/main/java/com/mashup/constant/ExtraConstant.kt
index 69e84909..0db4f406 100644
--- a/app/src/main/java/com/mashup/constant/ExtraConstant.kt
+++ b/app/src/main/java/com/mashup/constant/ExtraConstant.kt
@@ -1,5 +1,6 @@
package com.mashup.constant
+const val EXTRA_MAIN_TAB = "EXTRA_MAIN_TAB"
const val EXTRA_LOGIN_TYPE = "EXTRA_MAIN_TYPE"
const val EXTRA_TITLE_KEY = "EXTRA_TITLE_KEY"
@@ -10,3 +11,9 @@ const val EXTRA_LOGOUT = "EXTRA_LOGOUT"
const val EXTRA_WITH_DRAWL = "EXTRA_WITH_DRAWL"
const val EXTRA_ANIMATION = "EXTRA_ANIMATION"
+
+const val EXTRA_LINK = "link"
+
+const val EXTRA_POPUP_KEY = "EXTRA_POPUP_KEY"
+
+const val EXTRA_ACTIVITY_ENTER_TYPE = "EXTRA_ACTIVITY_ENTER_TYPE"
\ No newline at end of file
diff --git a/app/src/main/java/com/mashup/constant/log/UserActionLogs.kt b/app/src/main/java/com/mashup/constant/log/UserActionLogs.kt
index fb6e86f3..1edc9236 100644
--- a/app/src/main/java/com/mashup/constant/log/UserActionLogs.kt
+++ b/app/src/main/java/com/mashup/constant/log/UserActionLogs.kt
@@ -31,3 +31,9 @@ const val LOG_QR_TIME_FAIL = "qr_time_fail"
const val LOG_QR_WRONG = "qr_wrong"
const val LOG_DELETE_SUCCESS_USER = "delete_user_success"
+
+const val LOG_COMMON_POPUP_CONFIRM = "popup_new_confirm"
+const val LOG_COMMON_POPUP_CANCEL = "popup_new_cancel"
+
+const val LOG_DANGGN = "danggn"
+const val LOG_DANGGN_HELP = "danggn_help"
\ No newline at end of file
diff --git a/app/src/main/java/com/mashup/data/dto/AccessResponse.kt b/app/src/main/java/com/mashup/data/dto/AccessResponse.kt
index 6e4dfc81..44150384 100644
--- a/app/src/main/java/com/mashup/data/dto/AccessResponse.kt
+++ b/app/src/main/java/com/mashup/data/dto/AccessResponse.kt
@@ -15,6 +15,8 @@ class AccessResponse(
val platform: String,
@field:Json(name = "token")
val token: String,
- @field:Json(name = "pushNotificationAgreed")
- val pushNotificationAgreed: Boolean
+ @field:Json(name = "newsPushNotificationAgreed")
+ val pushNotificationAgreed: Boolean,
+ @field:Json(name = "danggnPushNotificationAgreed")
+ val danggnPushNotificationAgreed: Boolean
)
diff --git a/app/src/main/java/com/mashup/data/dto/MemberInfoResponse.kt b/app/src/main/java/com/mashup/data/dto/MemberInfoResponse.kt
index 54bdabad..b3d9ddb5 100644
--- a/app/src/main/java/com/mashup/data/dto/MemberInfoResponse.kt
+++ b/app/src/main/java/com/mashup/data/dto/MemberInfoResponse.kt
@@ -15,6 +15,8 @@ data class MemberInfoResponse(
val name: String,
@field:Json(name = "platform")
val platform: String,
- @field:Json(name = "pushNotificationAgreed")
- val pushNotificationAgreed: Boolean
+ @field:Json(name = "newsPushNotificationAgreed")
+ val pushNotificationAgreed: Boolean,
+ @field:Json(name = "danggnPushNotificationAgreed")
+ val danggnPushNotificationAgreed: Boolean
)
diff --git a/app/src/main/java/com/mashup/data/dto/PushNotificationRequest.kt b/app/src/main/java/com/mashup/data/dto/PushNotificationRequest.kt
index c66b6ed0..a887ce18 100644
--- a/app/src/main/java/com/mashup/data/dto/PushNotificationRequest.kt
+++ b/app/src/main/java/com/mashup/data/dto/PushNotificationRequest.kt
@@ -5,6 +5,8 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
class PushNotificationRequest(
- @field:Json(name = "pushNotificationAgreed")
- val pushNotificationAgreed: Boolean
+ @field:Json(name = "newsPushNotificationAgreed")
+ val pushNotificationAgreed: Boolean,
+ @field:Json(name = "danggnPushNotificationAgreed")
+ val danggnPushNotificationAgreed: Boolean
)
diff --git a/app/src/main/java/com/mashup/data/dto/StorageResponse.kt b/app/src/main/java/com/mashup/data/dto/StorageResponse.kt
new file mode 100644
index 00000000..4fc1e554
--- /dev/null
+++ b/app/src/main/java/com/mashup/data/dto/StorageResponse.kt
@@ -0,0 +1,12 @@
+package com.mashup.data.dto
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+data class StorageResponse(
+ @field:Json(name = "keyString")
+ val keyString: String,
+ @field:Json(name = "valueMap")
+ val valueMap: Map
+)
diff --git a/app/src/main/java/com/mashup/data/repository/MemberRepository.kt b/app/src/main/java/com/mashup/data/repository/MemberRepository.kt
index 81ea2913..966acfda 100644
--- a/app/src/main/java/com/mashup/data/repository/MemberRepository.kt
+++ b/app/src/main/java/com/mashup/data/repository/MemberRepository.kt
@@ -81,9 +81,13 @@ class MemberRepository @Inject constructor(
return memberDao.deleteMember()
}
- suspend fun patchPushNotification(pushNotificationAgreed: Boolean): Response {
+ suspend fun patchPushNotification(
+ pushNotificationAgreed: Boolean,
+ danggnPushNotificationAgreed: Boolean
+ ): Response {
val requestBody = PushNotificationRequest(
- pushNotificationAgreed = pushNotificationAgreed
+ pushNotificationAgreed = pushNotificationAgreed,
+ danggnPushNotificationAgreed = danggnPushNotificationAgreed
)
return memberDao.patchPushNotification(requestBody)
diff --git a/app/src/main/java/com/mashup/data/repository/PopUpRepository.kt b/app/src/main/java/com/mashup/data/repository/PopUpRepository.kt
new file mode 100644
index 00000000..8214761c
--- /dev/null
+++ b/app/src/main/java/com/mashup/data/repository/PopUpRepository.kt
@@ -0,0 +1,23 @@
+package com.mashup.data.repository
+
+import com.mashup.network.Response
+import com.mashup.network.dao.PopupDao
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class PopUpRepository @Inject constructor(
+ private val popupDao: PopupDao
+) {
+ suspend fun patchPopupViewed(popupType: String): Response {
+ return popupDao.patchPopupViewed(popupType)
+ }
+
+ suspend fun getPopupKeyList(): Response> {
+ return popupDao.getMembersPopupKeyList()
+ }
+
+ suspend fun patchPopupDisabled(popupType: String): Response {
+ return popupDao.patchPopupDisabled(popupType)
+ }
+}
diff --git a/app/src/main/java/com/mashup/data/repository/StorageRepository.kt b/app/src/main/java/com/mashup/data/repository/StorageRepository.kt
new file mode 100644
index 00000000..54d3bd3d
--- /dev/null
+++ b/app/src/main/java/com/mashup/data/repository/StorageRepository.kt
@@ -0,0 +1,16 @@
+package com.mashup.data.repository
+
+import com.mashup.data.dto.StorageResponse
+import com.mashup.network.Response
+import com.mashup.network.dao.StorageDao
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class StorageRepository @Inject constructor(
+ private val storageDao: StorageDao
+) {
+ suspend fun getStorage(key: String): Response {
+ return storageDao.getStorage(key)
+ }
+}
diff --git a/app/src/main/java/com/mashup/di/NetworkModule.kt b/app/src/main/java/com/mashup/di/NetworkModule.kt
index 52cc7462..3ac645f9 100644
--- a/app/src/main/java/com/mashup/di/NetworkModule.kt
+++ b/app/src/main/java/com/mashup/di/NetworkModule.kt
@@ -1,15 +1,20 @@
package com.mashup.di
+import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor
+import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
import com.mashup.BuildConfig.DEBUG_MODE
import com.mashup.data.network.API_HOST
import com.mashup.network.CustomDateAdapter
import com.mashup.network.dao.AttendanceDao
import com.mashup.network.dao.MemberDao
+import com.mashup.network.dao.PopupDao
import com.mashup.network.dao.ScheduleDao
import com.mashup.network.dao.ScoreDao
+import com.mashup.network.dao.StorageDao
import com.mashup.network.interceptor.AuthInterceptor
import com.mashup.network.interceptor.BaseInterceptor
import com.squareup.moshi.Moshi
+import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -26,28 +31,42 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
@Module
class NetworkModule {
+ companion object {
+ val flipperNetwork = NetworkFlipperPlugin()
+ }
+
@Provides
@Singleton
fun provideMoshi(): Moshi = Moshi.Builder()
.add(Date::class.java, CustomDateAdapter().nullSafe())
+ .addLast(KotlinJsonAdapterFactory())
.build()
+ @Provides
+ @Singleton
+ fun provideFlipperOkhttpInterceptor() =
+ FlipperOkhttpInterceptor(flipperNetwork)
+
@Provides
@Singleton
fun provideOkHttpClient(
authInterceptor: AuthInterceptor,
- baseInterceptor: BaseInterceptor
+ baseInterceptor: BaseInterceptor,
+ flipperInterceptor: FlipperOkhttpInterceptor,
): OkHttpClient {
+
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.addInterceptor(baseInterceptor)
if (DEBUG_MODE) {
- okHttpClient.addInterceptor(
- HttpLoggingInterceptor().apply {
- setLevel(HttpLoggingInterceptor.Level.BODY)
- }
- )
+ okHttpClient
+ .addNetworkInterceptor(flipperInterceptor)
+ .addInterceptor(
+ HttpLoggingInterceptor().apply {
+ setLevel(HttpLoggingInterceptor.Level.BODY)
+ }
+ )
}
return okHttpClient
.readTimeout(10L, TimeUnit.SECONDS)
@@ -99,4 +118,20 @@ class NetworkModule {
): ScoreDao {
return retrofit.create()
}
+
+ @Provides
+ @Singleton
+ fun provideStorageDao(
+ retrofit: Retrofit
+ ): StorageDao {
+ return retrofit.create()
+ }
+
+ @Provides
+ @Singleton
+ fun providePopupDao(
+ retrofit: Retrofit
+ ): PopupDao {
+ return retrofit.create()
+ }
}
diff --git a/app/src/main/java/com/mashup/network/dao/PopupDao.kt b/app/src/main/java/com/mashup/network/dao/PopupDao.kt
new file mode 100644
index 00000000..d459540e
--- /dev/null
+++ b/app/src/main/java/com/mashup/network/dao/PopupDao.kt
@@ -0,0 +1,21 @@
+package com.mashup.network.dao
+
+import com.mashup.network.Response
+import retrofit2.http.GET
+import retrofit2.http.PATCH
+import retrofit2.http.Path
+
+interface PopupDao {
+ @PATCH("/api/v1/member-popups/{popupType}/last-viewed")
+ suspend fun patchPopupViewed(
+ @Path("popupType") popupType: String
+ ): Response
+
+ @GET("/api/v1/member-popups")
+ suspend fun getMembersPopupKeyList(): Response>
+
+ @PATCH("/api/v1/member-popups/{popupType}/disabled")
+ suspend fun patchPopupDisabled(
+ @Path("popupType") popupType: String
+ ): Response
+}
diff --git a/app/src/main/java/com/mashup/network/dao/StorageDao.kt b/app/src/main/java/com/mashup/network/dao/StorageDao.kt
new file mode 100644
index 00000000..3c3c42af
--- /dev/null
+++ b/app/src/main/java/com/mashup/network/dao/StorageDao.kt
@@ -0,0 +1,13 @@
+package com.mashup.network.dao
+
+import com.mashup.data.dto.StorageResponse
+import com.mashup.network.Response
+import retrofit2.http.GET
+import retrofit2.http.Path
+
+interface StorageDao {
+ @GET("/api/v1/storage/key/{key}")
+ suspend fun getStorage(
+ @Path("key") key: String
+ ): Response
+}
diff --git a/app/src/main/java/com/mashup/network/interceptor/AuthInterceptor.kt b/app/src/main/java/com/mashup/network/interceptor/AuthInterceptor.kt
index 85df3de9..b1c9ae68 100644
--- a/app/src/main/java/com/mashup/network/interceptor/AuthInterceptor.kt
+++ b/app/src/main/java/com/mashup/network/interceptor/AuthInterceptor.kt
@@ -1,7 +1,7 @@
package com.mashup.network.interceptor
import com.mashup.datastore.data.repository.UserPreferenceRepository
-import com.mashup.network.errorcode.UNAUTHORIZED
+import com.mashup.core.common.constant.UNAUTHORIZED
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
diff --git a/app/src/main/java/com/mashup/util/MashUpFirebaseMessagingService.kt b/app/src/main/java/com/mashup/service/MashUpFirebaseMessagingService.kt
similarity index 88%
rename from app/src/main/java/com/mashup/util/MashUpFirebaseMessagingService.kt
rename to app/src/main/java/com/mashup/service/MashUpFirebaseMessagingService.kt
index a01306d5..d9ebc328 100644
--- a/app/src/main/java/com/mashup/util/MashUpFirebaseMessagingService.kt
+++ b/app/src/main/java/com/mashup/service/MashUpFirebaseMessagingService.kt
@@ -1,4 +1,4 @@
-package com.mashup.util
+package com.mashup.service
import android.app.NotificationChannel
import android.app.NotificationManager
@@ -16,8 +16,9 @@ import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.mashup.BuildConfig
import com.mashup.R
-import dagger.hilt.android.AndroidEntryPoint
+import com.mashup.constant.EXTRA_LINK
import com.mashup.ui.splash.SplashActivity
+import dagger.hilt.android.AndroidEntryPoint
import java.net.URL
@AndroidEntryPoint
@@ -40,13 +41,24 @@ class MashUpFirebaseMessagingService : FirebaseMessagingService() {
if (title != null && body != null) {
createNotificationChannel()
- notifyPushMessage(title, body, imageUrl)
+ notifyPushMessage(
+ title = title,
+ body = body,
+ imageUrl = imageUrl,
+ data = message.data
+ )
}
}
- private fun notifyPushMessage(title: String, body: String, imageUrl: Uri?) {
+ private fun notifyPushMessage(
+ title: String,
+ body: String,
+ imageUrl: Uri?,
+ data: Map
+ ) {
val splashIntent = Intent(this, SplashActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
+ putExtra(EXTRA_LINK, data[EXTRA_LINK])
}
val pendingIntent = PendingIntent.getActivity(
diff --git a/app/src/main/java/com/mashup/service/PushLinkType.kt b/app/src/main/java/com/mashup/service/PushLinkType.kt
new file mode 100644
index 00000000..6ab232cb
--- /dev/null
+++ b/app/src/main/java/com/mashup/service/PushLinkType.kt
@@ -0,0 +1,15 @@
+package com.mashup.service
+
+enum class PushLinkType {
+ MAIN, // 기본 페이지
+ QR, // QR 페이지
+ DANGGN, // 당근 페이지
+ MYPAGE,
+ UNKNOWN,
+ ;
+
+ companion object {
+ fun getPushLinkType(type: String) =
+ values().find { it.name == type } ?: UNKNOWN
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/mashup/ui/attendance/crew/CrewAttendanceActivity.kt b/app/src/main/java/com/mashup/ui/attendance/crew/CrewAttendanceActivity.kt
index 9df1c54e..30fec2e8 100644
--- a/app/src/main/java/com/mashup/ui/attendance/crew/CrewAttendanceActivity.kt
+++ b/app/src/main/java/com/mashup/ui/attendance/crew/CrewAttendanceActivity.kt
@@ -15,7 +15,7 @@ import com.mashup.core.common.model.NavigationAnimationType
import com.mashup.core.ui.theme.MashUpTheme
import com.mashup.data.model.PlatformInfo
import com.mashup.databinding.ActivityCrewAttendanceBinding
-import com.mashup.network.errorcode.SCHEDULE_NOT_FOUND
+import com.mashup.core.common.constant.SCHEDULE_NOT_FOUND
import com.mashup.ui.attendance.crew.CrewAttendanceViewModel.Companion.EXTRA_PLATFORM_KEY
import com.mashup.ui.attendance.crew.CrewAttendanceViewModel.Companion.EXTRA_SCHEDULE_ID
import dagger.hilt.android.AndroidEntryPoint
diff --git a/app/src/main/java/com/mashup/ui/attendance/crew/CrewAttendanceViewModel.kt b/app/src/main/java/com/mashup/ui/attendance/crew/CrewAttendanceViewModel.kt
index 67dca571..741d7543 100644
--- a/app/src/main/java/com/mashup/ui/attendance/crew/CrewAttendanceViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/attendance/crew/CrewAttendanceViewModel.kt
@@ -1,11 +1,11 @@
package com.mashup.ui.attendance.crew
import androidx.lifecycle.SavedStateHandle
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.data.dto.PlatformAttendanceResponse
import com.mashup.data.model.PlatformInfo
import com.mashup.data.repository.AttendanceRepository
-import com.mashup.network.errorcode.BAD_REQUEST
+import com.mashup.core.common.constant.BAD_REQUEST
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
diff --git a/app/src/main/java/com/mashup/ui/attendance/platform/PlatformAttendanceActivity.kt b/app/src/main/java/com/mashup/ui/attendance/platform/PlatformAttendanceActivity.kt
index 7884340e..0f8ef865 100644
--- a/app/src/main/java/com/mashup/ui/attendance/platform/PlatformAttendanceActivity.kt
+++ b/app/src/main/java/com/mashup/ui/attendance/platform/PlatformAttendanceActivity.kt
@@ -13,8 +13,8 @@ import com.mashup.core.common.model.NavigationAnimationType
import com.mashup.core.ui.theme.MashUpTheme
import com.mashup.data.model.PlatformInfo
import com.mashup.databinding.ActivityPlatformAttendanceBinding
-import com.mashup.network.errorcode.EVENT_NOT_FOUND
-import com.mashup.network.errorcode.SCHEDULE_NOT_FOUND
+import com.mashup.core.common.constant.EVENT_NOT_FOUND
+import com.mashup.core.common.constant.SCHEDULE_NOT_FOUND
import com.mashup.ui.attendance.crew.CrewAttendanceActivity
import dagger.hilt.android.AndroidEntryPoint
diff --git a/app/src/main/java/com/mashup/ui/attendance/platform/PlatformAttendanceViewModel.kt b/app/src/main/java/com/mashup/ui/attendance/platform/PlatformAttendanceViewModel.kt
index 8aeef089..aac42577 100644
--- a/app/src/main/java/com/mashup/ui/attendance/platform/PlatformAttendanceViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/attendance/platform/PlatformAttendanceViewModel.kt
@@ -3,7 +3,7 @@ package com.mashup.ui.attendance.platform
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.SavedStateHandle
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.constant.EXTRA_SCHEDULE_ID
import com.mashup.data.dto.TotalAttendanceResponse
import com.mashup.data.repository.AttendanceRepository
diff --git a/app/src/main/java/com/mashup/ui/danggn/DanggnInfoActivity.kt b/app/src/main/java/com/mashup/ui/danggn/DanggnInfoActivity.kt
new file mode 100644
index 00000000..0c83d346
--- /dev/null
+++ b/app/src/main/java/com/mashup/ui/danggn/DanggnInfoActivity.kt
@@ -0,0 +1,36 @@
+package com.mashup.ui.danggn
+
+import android.content.Context
+import android.content.Intent
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import com.mashup.R
+import com.mashup.base.BaseActivity
+import com.mashup.constant.EXTRA_ANIMATION
+import com.mashup.core.common.model.NavigationAnimationType
+import com.mashup.core.ui.theme.MashUpTheme
+import com.mashup.databinding.ActivityDanggnInfoBinding
+import com.mashup.feature.danggn.DanggnInfoScreen
+
+class DanggnInfoActivity : BaseActivity() {
+ override val layoutId: Int = R.layout.activity_danggn_info
+
+ override fun initViews() {
+ super.initViews()
+
+ viewBinding.shakeDanggnScreen.setContent {
+ MashUpTheme {
+ DanggnInfoScreen(
+ modifier = Modifier.fillMaxSize(),
+ onClickBackButton = { onBackPressed() },
+ )
+ }
+ }
+ }
+
+ companion object {
+ fun newIntent(context: Context) = Intent(context, DanggnInfoActivity::class.java).apply {
+ putExtra(EXTRA_ANIMATION, NavigationAnimationType.SLIDE)
+ }
+ }
+}
diff --git a/app/src/main/java/com/mashup/ui/danggn/ShakeDanggnActivity.kt b/app/src/main/java/com/mashup/ui/danggn/ShakeDanggnActivity.kt
new file mode 100644
index 00000000..4c92bec2
--- /dev/null
+++ b/app/src/main/java/com/mashup/ui/danggn/ShakeDanggnActivity.kt
@@ -0,0 +1,78 @@
+package com.mashup.ui.danggn
+
+import android.content.Context
+import android.content.Intent
+import androidx.activity.viewModels
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import com.mashup.R
+import com.mashup.base.BaseActivity
+import com.mashup.constant.EXTRA_ACTIVITY_ENTER_TYPE
+import com.mashup.constant.EXTRA_ANIMATION
+import com.mashup.constant.log.LOG_DANGGN
+import com.mashup.constant.log.LOG_DANGGN_HELP
+import com.mashup.core.common.model.ActivityEnterType
+import com.mashup.core.common.model.NavigationAnimationType
+import com.mashup.core.ui.theme.MashUpTheme
+import com.mashup.databinding.ActivityShakeDanggnBinding
+import com.mashup.feature.danggn.DanggnUiState
+import com.mashup.feature.danggn.DanggnViewModel
+import com.mashup.feature.danggn.ShakeDanggnScreen
+import com.mashup.feature.danggn.ranking.DanggnRankingViewModel
+import dagger.hilt.android.AndroidEntryPoint
+import kotlinx.coroutines.flow.collectLatest
+
+@AndroidEntryPoint
+class ShakeDanggnActivity : BaseActivity() {
+ override val layoutId: Int = R.layout.activity_shake_danggn
+
+ private val viewModel: DanggnViewModel by viewModels()
+ private val rankingViewModel: DanggnRankingViewModel by viewModels()
+
+ override fun initViews() {
+ super.initViews()
+ sendActivityEnterType(LOG_DANGGN)
+
+ viewBinding.shakeDanggnScreen.setContent {
+ MashUpTheme {
+ ShakeDanggnScreen(
+ modifier = Modifier.fillMaxSize(),
+ viewModel = viewModel,
+ rankingViewModel = rankingViewModel,
+ onClickBackButton = { onBackPressed() },
+ onClickDanggnInfoButton = { openDanggnInfoActivity() }
+ )
+ }
+ }
+ }
+
+ override fun initObserves() {
+ super.initObserves()
+ flowLifecycleScope {
+ viewModel.uiState.collectLatest { state ->
+ when (state) {
+ is DanggnUiState.Error -> {
+ handleCommonError(state.code)
+ }
+ else -> {}
+ }
+ }
+ }
+ }
+
+ private fun openDanggnInfoActivity() {
+ sendActivityEnterType(LOG_DANGGN_HELP)
+ val intent = DanggnInfoActivity.newIntent(this)
+ startActivity(intent)
+ }
+
+ companion object {
+ fun newIntent(
+ context: Context,
+ type: ActivityEnterType = ActivityEnterType.NORMAL
+ ) = Intent(context, ShakeDanggnActivity::class.java).apply {
+ putExtra(EXTRA_ANIMATION, NavigationAnimationType.SLIDE)
+ putExtra(EXTRA_ACTIVITY_ENTER_TYPE, type.name)
+ }
+ }
+}
diff --git a/app/src/main/java/com/mashup/ui/login/LoginActivity.kt b/app/src/main/java/com/mashup/ui/login/LoginActivity.kt
index d816c0c9..dde927a6 100644
--- a/app/src/main/java/com/mashup/ui/login/LoginActivity.kt
+++ b/app/src/main/java/com/mashup/ui/login/LoginActivity.kt
@@ -13,8 +13,8 @@ import com.mashup.constant.log.LOG_SIGN_UP
import com.mashup.core.common.extensions.onThrottleFirstClick
import com.mashup.core.common.model.Validation
import com.mashup.databinding.ActivityLoginBinding
-import com.mashup.network.errorcode.MEMBER_NOT_FOUND
-import com.mashup.network.errorcode.MEMBER_NOT_MATCH_PASSWORD
+import com.mashup.core.common.constant.MEMBER_NOT_FOUND
+import com.mashup.core.common.constant.MEMBER_NOT_MATCH_PASSWORD
import com.mashup.ui.main.MainActivity
import com.mashup.ui.signup.SignUpActivity
import com.mashup.util.AnalyticsManager
diff --git a/app/src/main/java/com/mashup/ui/login/LoginViewModel.kt b/app/src/main/java/com/mashup/ui/login/LoginViewModel.kt
index 40b18838..03e1f6e4 100644
--- a/app/src/main/java/com/mashup/ui/login/LoginViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/login/LoginViewModel.kt
@@ -1,17 +1,17 @@
package com.mashup.ui.login
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.core.common.model.Validation
import com.mashup.core.firebase.FirebaseRepository
import com.mashup.core.model.Platform
import com.mashup.data.repository.MemberRepository
import com.mashup.datastore.data.repository.UserPreferenceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
+import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
-import javax.inject.Inject
@HiltViewModel
class LoginViewModel @Inject constructor(
@@ -69,6 +69,7 @@ class LoginViewModel @Inject constructor(
response.data?.apply {
userPreferenceRepository.updateUserPreference(
+ id = memberId,
token = token,
name = name,
platform = Platform.getPlatform(platform),
diff --git a/app/src/main/java/com/mashup/ui/main/MainActivity.kt b/app/src/main/java/com/mashup/ui/main/MainActivity.kt
index 528e37d6..0a917bca 100644
--- a/app/src/main/java/com/mashup/ui/main/MainActivity.kt
+++ b/app/src/main/java/com/mashup/ui/main/MainActivity.kt
@@ -11,17 +11,24 @@ import com.mashup.R
import com.mashup.base.BaseActivity
import com.mashup.constant.EXTRA_ANIMATION
import com.mashup.constant.EXTRA_LOGIN_TYPE
+import com.mashup.constant.EXTRA_MAIN_TAB
import com.mashup.core.common.extensions.onThrottleFirstClick
import com.mashup.core.common.extensions.setStatusBarColorRes
import com.mashup.core.common.extensions.setStatusBarDarkTextColor
+import com.mashup.core.common.model.ActivityEnterType
import com.mashup.core.common.model.NavigationAnimationType
+import com.mashup.core.common.utils.safeShow
import com.mashup.databinding.ActivityMainBinding
+import com.mashup.ui.danggn.ShakeDanggnActivity
import com.mashup.ui.login.LoginType
+import com.mashup.ui.main.model.MainPopupType
import com.mashup.ui.main.model.MainTab
+import com.mashup.ui.main.popup.MainBottomPopup
import com.mashup.ui.qrscan.CongratsAttendanceScreen
import com.mashup.ui.qrscan.QRScanActivity
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.launch
@AndroidEntryPoint
class MainActivity : BaseActivity() {
@@ -80,10 +87,36 @@ class MainActivity : BaseActivity() {
override fun initObserves() {
super.initObserves()
flowLifecycleScope {
- viewModel.mainTab.collectLatest { tab ->
- navigationTab(tab)
- setUIOfTab(tab)
- updateStatusBarColor(tab)
+ launch {
+ viewModel.mainTab.collectLatest { tab ->
+ navigationTab(tab)
+ setUIOfTab(tab)
+ updateStatusBarColor(tab)
+ }
+ }
+
+ launch {
+ viewModel.showPopupType.collectLatest {
+ MainBottomPopup.newInstance(it).safeShow(supportFragmentManager)
+ }
+ }
+
+ launch {
+ viewModel.onClickPopupConfirm.collectLatest { popupType ->
+ when (popupType) {
+ MainPopupType.DANGGN -> {
+ viewModel.disablePopup(popupType)
+ startActivity(
+ ShakeDanggnActivity.newIntent(
+ context = this@MainActivity,
+ type = ActivityEnterType.POPUP
+ )
+ )
+ }
+ else -> {
+ }
+ }
+ }
}
}
}
@@ -150,10 +183,12 @@ class MainActivity : BaseActivity() {
companion object {
fun newIntent(
context: Context,
- loginType: LoginType
+ loginType: LoginType,
+ mainTab: MainTab = MainTab.EVENT
) = Intent(context, MainActivity::class.java).apply {
putExtra(EXTRA_ANIMATION, NavigationAnimationType.PULL)
putExtra(EXTRA_LOGIN_TYPE, loginType)
+ putExtra(EXTRA_MAIN_TAB, mainTab)
}
}
}
diff --git a/app/src/main/java/com/mashup/ui/main/MainViewModel.kt b/app/src/main/java/com/mashup/ui/main/MainViewModel.kt
index 870415b9..c308f6e9 100644
--- a/app/src/main/java/com/mashup/ui/main/MainViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/main/MainViewModel.kt
@@ -3,24 +3,29 @@ package com.mashup.ui.main
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.SavedStateHandle
-import com.mashup.base.BaseViewModel
import com.mashup.constant.EXTRA_LOGIN_TYPE
+import com.mashup.constant.EXTRA_MAIN_TAB
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.core.model.Platform
import com.mashup.data.repository.MemberRepository
+import com.mashup.data.repository.PopUpRepository
import com.mashup.datastore.data.repository.UserPreferenceRepository
import com.mashup.ui.login.LoginType
+import com.mashup.ui.main.model.MainPopupType
import com.mashup.ui.main.model.MainTab
import dagger.hilt.android.lifecycle.HiltViewModel
+import javax.inject.Inject
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
-import javax.inject.Inject
+import kotlinx.coroutines.flow.asSharedFlow
@HiltViewModel
class MainViewModel @Inject constructor(
private val memberRepository: MemberRepository,
+ private val popUpRepository: PopUpRepository,
private val userPreferenceRepository: UserPreferenceRepository,
savedStateHandle: SavedStateHandle
) : BaseViewModel() {
@@ -31,13 +36,23 @@ class MainViewModel @Inject constructor(
private val _onAttendance = MutableSharedFlow()
val onAttendance: SharedFlow = _onAttendance
- private val _successAttendance = MutableSharedFlow()
- val successAttendance: SharedFlow = _successAttendance
+ private val _showPopupType = MutableSharedFlow()
+ val showPopupType: SharedFlow = _showPopupType.asSharedFlow()
+
+ private val _onClickPopupConfirm = MutableSharedFlow()
+ val onClickPopupConfirm: SharedFlow = _onClickPopupConfirm.asSharedFlow()
+
init {
savedStateHandle.get(EXTRA_LOGIN_TYPE)?.run {
handleLoginType(this)
}
+
+ savedStateHandle.get(EXTRA_MAIN_TAB)?.run {
+ setMainTab(this)
+ }
+
+ getMainPopup()
}
private val _mainTab = MutableStateFlow(MainTab.EVENT)
@@ -49,7 +64,6 @@ class MainViewModel @Inject constructor(
fun successAttendance() = mashUpScope {
_isShowCongratsAttendanceScreen.value = true
- _successAttendance.emit(Unit)
delay(2000L)
_isShowCongratsAttendanceScreen.value = false
}
@@ -80,6 +94,7 @@ class MainViewModel @Inject constructor(
val result = memberRepository.getMember()
if (result.isSuccess() && result.data != null) {
userPreferenceRepository.updateUserPreference(
+ id = result.data.id,
name = result.data.name,
platform = Platform.getPlatform(result.data.platform),
generationNumbers = result.data.generationNumbers,
@@ -88,6 +103,28 @@ class MainViewModel @Inject constructor(
}
}
+ private fun getMainPopup() = mashUpScope {
+ val result = popUpRepository.getPopupKeyList()
+ if (result.isSuccess()) {
+ val popupType =
+ MainPopupType.getMainPopupType(result.data?.firstOrNull() ?: return@mashUpScope)
+ if (popupType == MainPopupType.UNKNOWN) return@mashUpScope
+ _showPopupType.emit(popupType)
+ }
+ }
+
+ fun disablePopup(popupKey: MainPopupType) = mashUpScope {
+ if (popupKey == MainPopupType.UNKNOWN) return@mashUpScope
+ popUpRepository.patchPopupDisabled(popupKey.name)
+ }
+
+ fun onClickPopup(popupKey: String) = mashUpScope {
+ val popupType =
+ MainPopupType.getMainPopupType(popupKey)
+ if (popupType == MainPopupType.UNKNOWN) return@mashUpScope
+ _onClickPopupConfirm.emit(popupType)
+ }
+
override fun handleErrorCode(code: String) {
}
}
diff --git a/app/src/main/java/com/mashup/ui/main/model/MainPopupEntity.kt b/app/src/main/java/com/mashup/ui/main/model/MainPopupEntity.kt
new file mode 100644
index 00000000..666c1582
--- /dev/null
+++ b/app/src/main/java/com/mashup/ui/main/model/MainPopupEntity.kt
@@ -0,0 +1,9 @@
+package com.mashup.ui.main.model
+
+data class MainPopupEntity(
+ val title: String,
+ val description: String,
+ val imageResName: String,
+ val leftButtonText: String,
+ val rightButtonText: String
+)
diff --git a/app/src/main/java/com/mashup/ui/main/model/MainPopupType.kt b/app/src/main/java/com/mashup/ui/main/model/MainPopupType.kt
new file mode 100644
index 00000000..63c65b4e
--- /dev/null
+++ b/app/src/main/java/com/mashup/ui/main/model/MainPopupType.kt
@@ -0,0 +1,11 @@
+package com.mashup.ui.main.model
+
+enum class MainPopupType {
+ DANGGN, UNKNOWN;
+
+ companion object {
+ fun getMainPopupType(type: String): MainPopupType {
+ return MainPopupType.values().find { it.name == type } ?: UNKNOWN
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/mashup/ui/main/popup/MainBottomPopup.kt b/app/src/main/java/com/mashup/ui/main/popup/MainBottomPopup.kt
new file mode 100644
index 00000000..63967f1e
--- /dev/null
+++ b/app/src/main/java/com/mashup/ui/main/popup/MainBottomPopup.kt
@@ -0,0 +1,248 @@
+package com.mashup.ui.main.popup
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewTreeObserver
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Divider
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment.Companion.CenterHorizontally
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.ViewCompositionStrategy
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.core.content.ContextCompat
+import androidx.core.os.bundleOf
+import androidx.fragment.app.activityViewModels
+import androidx.fragment.app.viewModels
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.google.android.material.bottomsheet.BottomSheetDialog
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import com.mashup.constant.EXTRA_POPUP_KEY
+import com.mashup.constant.log.LOG_COMMON_POPUP_CANCEL
+import com.mashup.constant.log.LOG_COMMON_POPUP_CONFIRM
+import com.mashup.core.common.utils.getDrawableResIdByName
+import com.mashup.core.ui.colors.Gray500
+import com.mashup.core.ui.colors.Gray950
+import com.mashup.core.ui.colors.White
+import com.mashup.core.ui.theme.MashUpTheme
+import com.mashup.core.ui.typography.Body4
+import com.mashup.core.ui.typography.SubTitle1
+import com.mashup.core.ui.widget.ButtonStyle
+import com.mashup.core.ui.widget.MashUpButton
+import com.mashup.ui.main.MainViewModel
+import com.mashup.ui.main.model.MainPopupEntity
+import com.mashup.ui.main.model.MainPopupType
+import com.mashup.util.AnalyticsManager
+import dagger.hilt.android.AndroidEntryPoint
+
+
+@AndroidEntryPoint
+class MainBottomPopup : BottomSheetDialogFragment() {
+
+ private val mainViewModel: MainViewModel by activityViewModels()
+
+ companion object {
+ fun newInstance(popupType: MainPopupType) = MainBottomPopup().apply {
+ arguments = bundleOf(
+ EXTRA_POPUP_KEY to popupType.name
+ )
+ }
+ }
+
+
+ private val viewModel: MainBottomPopupViewModel by viewModels()
+
+ private val behavior: BottomSheetBehavior?
+ get() {
+ val bottomSheet =
+ dialog?.findViewById(com.google.android.material.R.id.design_bottom_sheet)
+ return bottomSheet?.let {
+ BottomSheetBehavior.from(bottomSheet)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ viewModel.patchPopupViewed()
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ return ComposeView(requireContext()).apply {
+ setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
+
+ setContent {
+ MashUpTheme {
+ MainBottomPopupScreen(
+ viewModel = viewModel,
+ onClickLeftButton = {
+ AnalyticsManager.addEvent(LOG_COMMON_POPUP_CANCEL, bundleOf("key" to viewModel.popupKey))
+ dismiss()
+ },
+ onClickRightButton = {
+ mainViewModel.onClickPopup(viewModel.popupKey ?: "")
+ AnalyticsManager.addEvent(LOG_COMMON_POPUP_CONFIRM, bundleOf("key" to viewModel.popupKey))
+ dismiss()
+ }
+ )
+ }
+ }
+ }
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val bottomSheetDialog = dialog as? BottomSheetDialog
+ bottomSheetDialog?.findViewById(com.google.android.material.R.id.design_bottom_sheet)
+ ?.run {
+ setBackgroundColor(
+ ContextCompat.getColor(
+ requireContext(),
+ android.R.color.transparent
+ )
+ )
+ }
+
+ addGlobalLayoutListener(view)
+ }
+
+ private fun addGlobalLayoutListener(view: View) {
+ view.viewTreeObserver.addOnGlobalLayoutListener(object :
+ ViewTreeObserver.OnGlobalLayoutListener {
+ override fun onGlobalLayout() {
+ if (this@MainBottomPopup.view?.height == 0) return
+ view.viewTreeObserver.removeOnGlobalLayoutListener(this)
+ behavior?.state = BottomSheetBehavior.STATE_EXPANDED
+ behavior?.peekHeight = this@MainBottomPopup.view?.height ?: 0
+ }
+ })
+ }
+}
+
+@Composable
+fun MainBottomPopupScreen(
+ viewModel: MainBottomPopupViewModel,
+ onClickLeftButton: () -> Unit = {},
+ onClickRightButton: () -> Unit = {}
+) {
+ val uiState: MainBottomPopupUiState by viewModel.uiState
+
+ (uiState as? MainBottomPopupUiState.Success)?.let {
+ MainBottomPopupContent(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight()
+ .padding(20.dp),
+ mainPopupEntity = it.mainPopupEntity,
+ onClickLeftButton = onClickLeftButton,
+ onClickRightButton = onClickRightButton
+ )
+ }
+}
+
+
+@Composable
+fun MainBottomPopupContent(
+ mainPopupEntity: MainPopupEntity,
+ modifier: Modifier = Modifier,
+ onClickLeftButton: () -> Unit = {},
+ onClickRightButton: () -> Unit = {}
+) {
+ Column(
+ modifier = modifier
+ .background(
+ color = White,
+ shape = RoundedCornerShape(20.dp)
+ )
+ ) {
+ Divider(
+ modifier = Modifier
+ .width(24.dp)
+ .align(CenterHorizontally)
+ .padding(vertical = 10.dp),
+ color = Color(0xFFD9D9D9),
+ thickness = 3.dp
+ )
+
+ Text(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(top = 8.dp)
+ .padding(horizontal = 20.dp),
+ text = mainPopupEntity.title,
+ style = SubTitle1,
+ color = Gray950,
+ textAlign = TextAlign.Center
+ )
+
+ Text(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 20.dp, vertical = 8.dp),
+ text = mainPopupEntity.description,
+ style = Body4,
+ color = Gray500,
+ textAlign = TextAlign.Center
+ )
+
+ val context = LocalContext.current
+ val imageResId = remember(mainPopupEntity.imageResName) {
+ context.getDrawableResIdByName(mainPopupEntity.imageResName)
+ }
+ Image(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 20.dp, vertical = 16.dp),
+ painter = painterResource(id = imageResId),
+ contentDescription = null
+ )
+
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 20.dp),
+ horizontalArrangement = Arrangement.spacedBy(12.dp)
+ ) {
+ MashUpButton(
+ modifier = Modifier.wrapContentWidth(),
+ text = mainPopupEntity.leftButtonText,
+ buttonStyle = ButtonStyle.INVERSE,
+ onClick = onClickLeftButton
+ )
+
+ MashUpButton(
+ modifier = Modifier.weight(1f),
+ text = mainPopupEntity.rightButtonText,
+ buttonStyle = ButtonStyle.PRIMARY,
+ onClick = onClickRightButton
+ )
+ }
+
+ Spacer(modifier = Modifier.height(24.dp))
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/mashup/ui/main/popup/MainBottomPopupViewModel.kt b/app/src/main/java/com/mashup/ui/main/popup/MainBottomPopupViewModel.kt
new file mode 100644
index 00000000..482c37da
--- /dev/null
+++ b/app/src/main/java/com/mashup/ui/main/popup/MainBottomPopupViewModel.kt
@@ -0,0 +1,58 @@
+package com.mashup.ui.main.popup
+
+import androidx.compose.runtime.State
+import androidx.compose.runtime.mutableStateOf
+import androidx.lifecycle.SavedStateHandle
+import com.mashup.constant.EXTRA_POPUP_KEY
+import com.mashup.core.common.base.BaseViewModel
+import com.mashup.data.repository.PopUpRepository
+import com.mashup.data.repository.StorageRepository
+import com.mashup.ui.main.model.MainPopupEntity
+import dagger.hilt.android.lifecycle.HiltViewModel
+import javax.inject.Inject
+
+@HiltViewModel
+class MainBottomPopupViewModel @Inject constructor(
+ private val storageRepository: StorageRepository,
+ private val popUpRepository: PopUpRepository,
+ savedStateHandle: SavedStateHandle
+) : BaseViewModel() {
+ val popupKey = savedStateHandle.get(EXTRA_POPUP_KEY)
+
+ private val _uiState = mutableStateOf(MainBottomPopupUiState.Loading)
+ val uiState: State = _uiState
+
+ init {
+ getStorage()
+ }
+
+ private fun getStorage() = mashUpScope {
+ if (popupKey.isNullOrBlank()) return@mashUpScope
+ val result = storageRepository.getStorage(popupKey)
+
+ if (result.isSuccess()) {
+ _uiState.value = MainBottomPopupUiState.Success(
+ MainPopupEntity(
+ title = result.data?.valueMap?.get("title") ?: "",
+ description = result.data?.valueMap?.get("subtitle") ?: "",
+ imageResName = result.data?.valueMap?.get("imageName") ?: "",
+ leftButtonText = result.data?.valueMap?.get("leftButtonTitle") ?: "",
+ rightButtonText = result.data?.valueMap?.get("rightButtonTitle") ?: ""
+ )
+ )
+ }
+ }
+
+ fun patchPopupViewed() = mashUpScope {
+ if (popupKey.isNullOrBlank()) return@mashUpScope
+ popUpRepository.patchPopupViewed(popupKey)
+ }
+}
+
+sealed interface MainBottomPopupUiState {
+ object Loading : MainBottomPopupUiState
+
+ data class Success(
+ val mainPopupEntity: MainPopupEntity
+ ) : MainBottomPopupUiState
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/mashup/ui/mypage/MyPageViewModel.kt b/app/src/main/java/com/mashup/ui/mypage/MyPageViewModel.kt
index 1ccd5de5..74d71c2b 100644
--- a/app/src/main/java/com/mashup/ui/mypage/MyPageViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/mypage/MyPageViewModel.kt
@@ -2,7 +2,7 @@ package com.mashup.ui.mypage
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.data.dto.ScoreHistoryResponse
import com.mashup.data.repository.MyPageRepository
import com.mashup.datastore.data.repository.UserPreferenceRepository
diff --git a/app/src/main/java/com/mashup/ui/qrscan/QRScanActivity.kt b/app/src/main/java/com/mashup/ui/qrscan/QRScanActivity.kt
index 5182a73f..6b4c8d39 100644
--- a/app/src/main/java/com/mashup/ui/qrscan/QRScanActivity.kt
+++ b/app/src/main/java/com/mashup/ui/qrscan/QRScanActivity.kt
@@ -29,7 +29,7 @@ import com.mashup.network.errorcode.ATTENDANCE_CODE_INVALID
import com.mashup.network.errorcode.ATTENDANCE_CODE_NOT_FOUND
import com.mashup.network.errorcode.ATTENDANCE_TIME_BEFORE
import com.mashup.network.errorcode.ATTENDANCE_TIME_OVER
-import com.mashup.network.errorcode.MEMBER_NOT_FOUND
+import com.mashup.core.common.constant.MEMBER_NOT_FOUND
import com.mashup.ui.qrscan.camera.CameraManager
import com.mashup.util.AnalyticsManager
import dagger.hilt.android.AndroidEntryPoint
diff --git a/app/src/main/java/com/mashup/ui/qrscan/QRScanViewModel.kt b/app/src/main/java/com/mashup/ui/qrscan/QRScanViewModel.kt
index 3dcf8743..be70daf5 100644
--- a/app/src/main/java/com/mashup/ui/qrscan/QRScanViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/qrscan/QRScanViewModel.kt
@@ -1,7 +1,7 @@
package com.mashup.ui.qrscan
import androidx.lifecycle.viewModelScope
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.data.repository.AttendanceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
diff --git a/app/src/main/java/com/mashup/ui/schedule/ScheduleFragment.kt b/app/src/main/java/com/mashup/ui/schedule/ScheduleFragment.kt
index 4b7ca19d..54ac5b23 100644
--- a/app/src/main/java/com/mashup/ui/schedule/ScheduleFragment.kt
+++ b/app/src/main/java/com/mashup/ui/schedule/ScheduleFragment.kt
@@ -13,7 +13,6 @@ import androidx.viewpager2.widget.ViewPager2
import com.mashup.R
import com.mashup.base.BaseFragment
import com.mashup.constant.log.LOG_SCHEDULE_EVENT_DETAIL
-import com.mashup.constant.log.LOG_SCHEDULE_LIST_REFRESH
import com.mashup.constant.log.LOG_SCHEDULE_STATUS_CONFIRM
import com.mashup.core.common.extensions.fromHtml
import com.mashup.core.common.extensions.gone
@@ -21,7 +20,9 @@ import com.mashup.core.common.extensions.onThrottleFirstClick
import com.mashup.core.common.extensions.visible
import com.mashup.databinding.FragmentScheduleBinding
import com.mashup.ui.attendance.platform.PlatformAttendanceActivity
+import com.mashup.ui.danggn.ShakeDanggnActivity
import com.mashup.ui.main.MainViewModel
+import com.mashup.ui.main.model.MainPopupType
import com.mashup.ui.schedule.adapter.OnItemClickListener
import com.mashup.ui.schedule.adapter.ScheduleViewPagerAdapter
import com.mashup.ui.schedule.detail.ScheduleDetailActivity
@@ -78,6 +79,7 @@ class ScheduleFragment : BaseFragment() {
super.initViews()
initSwipeRefreshLayout()
initViewPager()
+ initButtons()
}
private fun initSwipeRefreshLayout() {
@@ -121,6 +123,15 @@ class ScheduleFragment : BaseFragment() {
offscreenPageLimit = 4
}
}
+
+ private fun initButtons() {
+ viewBinding.btnDanggnEntryPoint.onThrottleFirstClick(lifecycleScope) {
+ mainViewModel.disablePopup(MainPopupType.DANGGN)
+ startActivity(
+ ShakeDanggnActivity.newIntent(requireContext())
+ )
+ }
+ }
override fun initObserves() {
flowViewLifecycleScope {
diff --git a/app/src/main/java/com/mashup/ui/schedule/ScheduleViewModel.kt b/app/src/main/java/com/mashup/ui/schedule/ScheduleViewModel.kt
index f7704115..9bbe0a54 100644
--- a/app/src/main/java/com/mashup/ui/schedule/ScheduleViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/schedule/ScheduleViewModel.kt
@@ -1,6 +1,6 @@
package com.mashup.ui.schedule
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.data.dto.ScheduleResponse
import com.mashup.data.dto.SchedulesProgress
import com.mashup.data.repository.AttendanceRepository
diff --git a/app/src/main/java/com/mashup/ui/schedule/detail/ScheduleDetailActivity.kt b/app/src/main/java/com/mashup/ui/schedule/detail/ScheduleDetailActivity.kt
index 4fe7eef4..e62a84c0 100644
--- a/app/src/main/java/com/mashup/ui/schedule/detail/ScheduleDetailActivity.kt
+++ b/app/src/main/java/com/mashup/ui/schedule/detail/ScheduleDetailActivity.kt
@@ -7,7 +7,7 @@ import com.mashup.R
import com.mashup.base.BaseActivity
import com.mashup.constant.EXTRA_SCHEDULE_ID
import com.mashup.databinding.ActivityScheduleDetailBinding
-import com.mashup.network.errorcode.SCHEDULE_NOT_FOUND
+import com.mashup.core.common.constant.SCHEDULE_NOT_FOUND
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
diff --git a/app/src/main/java/com/mashup/ui/schedule/detail/ScheduleDetailViewModel.kt b/app/src/main/java/com/mashup/ui/schedule/detail/ScheduleDetailViewModel.kt
index 6ef61e2d..a476690d 100644
--- a/app/src/main/java/com/mashup/ui/schedule/detail/ScheduleDetailViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/schedule/detail/ScheduleDetailViewModel.kt
@@ -1,7 +1,7 @@
package com.mashup.ui.schedule.detail
import androidx.lifecycle.SavedStateHandle
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.constant.EXTRA_SCHEDULE_ID
import com.mashup.data.dto.EventResponse
import com.mashup.data.repository.ScheduleRepository
diff --git a/app/src/main/java/com/mashup/ui/setting/PushActivity.kt b/app/src/main/java/com/mashup/ui/setting/PushActivity.kt
new file mode 100644
index 00000000..0c2d6250
--- /dev/null
+++ b/app/src/main/java/com/mashup/ui/setting/PushActivity.kt
@@ -0,0 +1,62 @@
+package com.mashup.ui.setting
+
+import android.content.Context
+import android.content.Intent
+import androidx.activity.viewModels
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import com.mashup.R
+import com.mashup.base.BaseActivity
+import com.mashup.constant.EXTRA_ANIMATION
+import com.mashup.core.common.model.NavigationAnimationType
+import com.mashup.core.model.data.local.UserPreference
+import com.mashup.core.ui.theme.MashUpTheme
+import com.mashup.databinding.ActivitySettingBinding
+import com.mashup.feature.setting.ui.push.PushScreen
+import dagger.hilt.android.AndroidEntryPoint
+
+@AndroidEntryPoint
+class PushActivity : BaseActivity() {
+
+ private val viewModel: SettingViewModel by viewModels()
+
+ override fun initViews() {
+ super.initViews()
+
+ viewBinding.settingScreen.setContent {
+ MashUpTheme {
+ val userPreference by viewModel.userPreference.collectAsState(
+ initial = UserPreference.getDefaultInstance()
+ )
+
+ PushScreen(
+ modifier = Modifier.fillMaxSize(),
+ onToggleMashUpPush = this::onToggleMashUpPush,
+ onToggleDanggnPush = this::onToggleDanggnPush,
+ userPreference = userPreference,
+ onClickBackButton = {
+ onBackPressed()
+ }
+ )
+ }
+ }
+ }
+
+ private fun onToggleMashUpPush(isChecked: Boolean) {
+ viewModel.patchPushNotification(isChecked)
+ }
+
+ private fun onToggleDanggnPush(isChecked: Boolean) {
+ viewModel.patchDanggnPushNotification(isChecked)
+ }
+
+ companion object {
+ fun newIntent(context: Context) = Intent(context, PushActivity::class.java).apply {
+ putExtra(EXTRA_ANIMATION, NavigationAnimationType.PULL)
+ }
+ }
+
+ override val layoutId = R.layout.activity_setting
+}
diff --git a/app/src/main/java/com/mashup/ui/setting/SettingActivity.kt b/app/src/main/java/com/mashup/ui/setting/SettingActivity.kt
index dafdefd8..84ddbadc 100644
--- a/app/src/main/java/com/mashup/ui/setting/SettingActivity.kt
+++ b/app/src/main/java/com/mashup/ui/setting/SettingActivity.kt
@@ -25,7 +25,7 @@ import com.mashup.core.common.widget.CommonDialog
import com.mashup.core.model.data.local.UserPreference
import com.mashup.core.ui.theme.MashUpTheme
import com.mashup.databinding.ActivitySettingBinding
-import com.mashup.feature.SettingScreen
+import com.mashup.feature.setting.SettingScreen
import com.mashup.ui.login.LoginActivity
import com.mashup.ui.withdrawl.WithdrawalActivity
import com.mashup.util.AnalyticsManager
@@ -42,20 +42,13 @@ class SettingActivity : BaseActivity() {
viewBinding.settingScreen.setContent {
MashUpTheme {
- val userPreference by viewModel.userPreference.collectAsState(
- initial = UserPreference.getDefaultInstance()
- )
-
SettingScreen(
modifier = Modifier.fillMaxSize(),
onLogout = this::onClickLogoutButton,
onDeleteUser = this::moveToDeleteAccount,
- onToggleFcm = this::onToggleFcm,
onClickSNS = this::onClickSNS,
- userPreference = userPreference,
- onClickBackButton = {
- onBackPressed()
- }
+ onClickPush = this::moveToPushActivity,
+ onClickBackButton = this::onBackPressed
)
}
}
@@ -96,6 +89,14 @@ class SettingActivity : BaseActivity() {
)
}
+ private fun moveToPushActivity() {
+ startActivity(
+ PushActivity.newIntent(
+ context = this@SettingActivity
+ )
+ )
+ }
+
private fun moveToDeleteAccount() {
AnalyticsManager.addEvent(LOG_DELETE_USER)
startActivity(
@@ -117,13 +118,9 @@ class SettingActivity : BaseActivity() {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(link)))
}
- private fun onToggleFcm(isChecked: Boolean) {
- viewModel.patchPushNotification(isChecked)
- }
-
companion object {
fun newIntent(context: Context) = Intent(context, SettingActivity::class.java).apply {
- putExtra(EXTRA_ANIMATION, NavigationAnimationType.PULL)
+ putExtra(EXTRA_ANIMATION, NavigationAnimationType.SLIDE)
}
}
diff --git a/app/src/main/java/com/mashup/ui/setting/SettingViewModel.kt b/app/src/main/java/com/mashup/ui/setting/SettingViewModel.kt
index 4423936a..6b49c3b4 100644
--- a/app/src/main/java/com/mashup/ui/setting/SettingViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/setting/SettingViewModel.kt
@@ -1,11 +1,15 @@
package com.mashup.ui.setting
-import com.mashup.base.BaseViewModel
+import androidx.lifecycle.viewModelScope
+import com.mashup.core.common.base.BaseViewModel
+import com.mashup.core.model.data.local.UserPreference
import com.mashup.data.repository.MemberRepository
import com.mashup.datastore.data.repository.UserPreferenceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.stateIn
import javax.inject.Inject
@HiltViewModel
@@ -13,7 +17,11 @@ class SettingViewModel @Inject constructor(
private val userPreferenceRepository: UserPreferenceRepository,
private val memberRepository: MemberRepository
) : BaseViewModel() {
- val userPreference = userPreferenceRepository.getUserPreference()
+ val userPreference = userPreferenceRepository.getUserPreference().stateIn(
+ viewModelScope,
+ SharingStarted.WhileSubscribed(5_000),
+ UserPreference.getDefaultInstance()
+ )
private val _onSuccessLogout = MutableSharedFlow()
val onSuccessLogout: SharedFlow = _onSuccessLogout
@@ -23,10 +31,35 @@ class SettingViewModel @Inject constructor(
_onSuccessLogout.emit(Unit)
}
- fun patchPushNotification(pushNotificationAgreed: Boolean) = mashUpScope {
- val result = memberRepository.patchPushNotification(pushNotificationAgreed)
+ fun patchPushNotification(
+ pushNotificationAgreed: Boolean
+ ) = mashUpScope {
+ val danggnPushAgreed = userPreference.value.danggnPushNotificationAgreed
+ val result = memberRepository.patchPushNotification(
+ pushNotificationAgreed = pushNotificationAgreed,
+ danggnPushNotificationAgreed = danggnPushAgreed
+ )
if (result.isSuccess()) {
- userPreferenceRepository.updateUserPushNotificationAgreed(pushNotificationAgreed)
+ userPreferenceRepository.updateUserPushNotificationAgreed(
+ pushNotificationAgreed = pushNotificationAgreed,
+ danggnPushNotificationAgreed = danggnPushAgreed
+ )
+ }
+ }
+
+ fun patchDanggnPushNotification(
+ danggnPushNotificationAgreed: Boolean
+ ) = mashUpScope {
+ val pushNotificationAgreed = userPreference.value.pushNotificationAgreed
+ val result = memberRepository.patchPushNotification(
+ pushNotificationAgreed = pushNotificationAgreed,
+ danggnPushNotificationAgreed = danggnPushNotificationAgreed
+ )
+ if (result.isSuccess()) {
+ userPreferenceRepository.updateUserPushNotificationAgreed(
+ pushNotificationAgreed = pushNotificationAgreed,
+ danggnPushNotificationAgreed = danggnPushNotificationAgreed
+ )
}
}
diff --git a/app/src/main/java/com/mashup/ui/signup/SignUpViewModel.kt b/app/src/main/java/com/mashup/ui/signup/SignUpViewModel.kt
index 4951dbfa..5dea1df6 100644
--- a/app/src/main/java/com/mashup/ui/signup/SignUpViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/signup/SignUpViewModel.kt
@@ -1,6 +1,6 @@
package com.mashup.ui.signup
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.core.common.model.Validation
import com.mashup.core.firebase.FirebaseRepository
import com.mashup.core.model.Platform
@@ -8,6 +8,7 @@ import com.mashup.data.repository.MemberRepository
import com.mashup.datastore.data.repository.UserPreferenceRepository
import com.mashup.ui.signup.state.CodeState
import dagger.hilt.android.lifecycle.HiltViewModel
+import javax.inject.Inject
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
@@ -15,7 +16,6 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.map
-import javax.inject.Inject
@HiltViewModel
class SignUpViewModel @Inject constructor(
@@ -81,6 +81,7 @@ class SignUpViewModel @Inject constructor(
response.data?.run {
userPreferenceRepository.updateUserPreference(
+ id = memberId,
token = token,
name = name,
platform = Platform.getPlatform(platform),
diff --git a/app/src/main/java/com/mashup/ui/signup/fragment/SignUpCodeFragment.kt b/app/src/main/java/com/mashup/ui/signup/fragment/SignUpCodeFragment.kt
index 806cdd78..67d186fe 100644
--- a/app/src/main/java/com/mashup/ui/signup/fragment/SignUpCodeFragment.kt
+++ b/app/src/main/java/com/mashup/ui/signup/fragment/SignUpCodeFragment.kt
@@ -13,8 +13,8 @@ import com.mashup.core.common.model.Validation
import com.mashup.core.common.utils.keyboard.TranslateDeferringInsetsAnimationCallback
import com.mashup.databinding.FragmentSignUpCodeBinding
import com.mashup.network.errorcode.ATTENDANCE_CODE_DUPLICATED
-import com.mashup.network.errorcode.INVALID_PLATFORM_NAME
-import com.mashup.network.errorcode.MEMBER_INVALID_INVITE
+import com.mashup.core.common.constant.INVALID_PLATFORM_NAME
+import com.mashup.core.common.constant.MEMBER_INVALID_INVITE
import com.mashup.ui.login.LoginType
import com.mashup.ui.main.MainActivity
import com.mashup.ui.signup.SignUpState
diff --git a/app/src/main/java/com/mashup/ui/signup/fragment/auth/SignUpAuthFragment.kt b/app/src/main/java/com/mashup/ui/signup/fragment/auth/SignUpAuthFragment.kt
index c27a17e1..d7136aa9 100644
--- a/app/src/main/java/com/mashup/ui/signup/fragment/auth/SignUpAuthFragment.kt
+++ b/app/src/main/java/com/mashup/ui/signup/fragment/auth/SignUpAuthFragment.kt
@@ -14,7 +14,7 @@ import com.mashup.core.common.extensions.setFailedUiOfTextField
import com.mashup.core.common.extensions.setSuccessUiOfTextField
import com.mashup.core.common.utils.keyboard.TranslateDeferringInsetsAnimationCallback
import com.mashup.databinding.FragmentSignUpAuthBinding
-import com.mashup.network.errorcode.MEMBER_DUPLICATED_IDENTIFICATION
+import com.mashup.core.common.constant.MEMBER_DUPLICATED_IDENTIFICATION
import com.mashup.ui.signup.SignUpViewModel
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
diff --git a/app/src/main/java/com/mashup/ui/signup/fragment/auth/SignUpAuthViewModel.kt b/app/src/main/java/com/mashup/ui/signup/fragment/auth/SignUpAuthViewModel.kt
index 3c55351c..c7430eac 100644
--- a/app/src/main/java/com/mashup/ui/signup/fragment/auth/SignUpAuthViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/signup/fragment/auth/SignUpAuthViewModel.kt
@@ -1,11 +1,11 @@
package com.mashup.ui.signup.fragment.auth
import androidx.lifecycle.viewModelScope
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.core.common.model.Validation
import com.mashup.data.repository.MemberRepository
-import com.mashup.network.errorcode.INVALID_MEMBER_ID
-import com.mashup.network.errorcode.MEMBER_DUPLICATED_IDENTIFICATION
+import com.mashup.core.common.constant.INVALID_MEMBER_ID
+import com.mashup.core.common.constant.MEMBER_DUPLICATED_IDENTIFICATION
import com.mashup.ui.signup.validationId
import com.mashup.ui.signup.validationPwd
import com.mashup.ui.signup.validationPwdCheck
diff --git a/app/src/main/java/com/mashup/ui/splash/SplashActivity.kt b/app/src/main/java/com/mashup/ui/splash/SplashActivity.kt
index b2b84033..12a0ffdf 100644
--- a/app/src/main/java/com/mashup/ui/splash/SplashActivity.kt
+++ b/app/src/main/java/com/mashup/ui/splash/SplashActivity.kt
@@ -5,17 +5,25 @@ import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.viewModels
+import androidx.core.app.TaskStackBuilder
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.mashup.R
import com.mashup.base.BaseActivity
+import com.mashup.constant.EXTRA_LINK
import com.mashup.core.common.extensions.setStatusBarColorRes
import com.mashup.core.common.extensions.setStatusBarDarkTextColor
+import com.mashup.core.common.model.ActivityEnterType
import com.mashup.core.common.widget.CommonDialog
import com.mashup.databinding.ActivitySplashBinding
import com.mashup.datastore.data.repository.UserPreferenceRepository
-import com.mashup.ui.login.LoginActivity
+import com.mashup.service.PushLinkType
+import com.mashup.ui.danggn.ShakeDanggnActivity
+import com.mashup.ui.login.LoginType
+import com.mashup.ui.main.MainActivity
+import com.mashup.ui.main.model.MainTab
+import com.mashup.ui.qrscan.QRScanActivity
import com.mashup.util.AnalyticsManager
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
@@ -77,7 +85,34 @@ class SplashActivity : BaseActivity() {
}
private fun moveNextScreen() {
- startActivity(LoginActivity.newIntent(this@SplashActivity))
+ val deepLink = intent.getStringExtra(EXTRA_LINK) ?: ""
+ val baseIntent = MainActivity.newIntent(
+ context = this@SplashActivity,
+ loginType = LoginType.AUTO,
+ mainTab = if (deepLink == PushLinkType.MYPAGE.name) MainTab.MY_PAGE else MainTab.EVENT
+ )
+ val taskStackBuilder = when (PushLinkType.getPushLinkType(deepLink)) {
+ PushLinkType.DANGGN -> {
+ TaskStackBuilder.create(this)
+ .addNextIntentWithParentStack(baseIntent)
+ .addNextIntent(
+ ShakeDanggnActivity.newIntent(
+ context = this,
+ type = ActivityEnterType.ALARM
+ )
+ )
+ }
+ PushLinkType.QR -> {
+ TaskStackBuilder.create(this)
+ .addNextIntentWithParentStack(baseIntent)
+ .addNextIntent(QRScanActivity.newIntent(this))
+ }
+ else -> {
+ TaskStackBuilder.create(this)
+ .addNextIntentWithParentStack(baseIntent)
+ }
+ }
+ taskStackBuilder.startActivities()
finish()
}
diff --git a/app/src/main/java/com/mashup/ui/splash/SplashViewModel.kt b/app/src/main/java/com/mashup/ui/splash/SplashViewModel.kt
index 20a4fff9..4b5df6a7 100644
--- a/app/src/main/java/com/mashup/ui/splash/SplashViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/splash/SplashViewModel.kt
@@ -2,7 +2,7 @@ package com.mashup.ui.splash
import android.content.Context
import androidx.core.content.pm.PackageInfoCompat
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.core.firebase.FirebaseRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CancellationException
diff --git a/app/src/main/java/com/mashup/ui/webview/WebViewViewModel.kt b/app/src/main/java/com/mashup/ui/webview/WebViewViewModel.kt
index 8525a59a..1ef8db98 100644
--- a/app/src/main/java/com/mashup/ui/webview/WebViewViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/webview/WebViewViewModel.kt
@@ -2,7 +2,7 @@ package com.mashup.ui.webview
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.constant.EXTRA_TITLE_KEY
import com.mashup.constant.EXTRA_URL_KEY
import dagger.hilt.android.lifecycle.HiltViewModel
diff --git a/app/src/main/java/com/mashup/ui/withdrawl/WithdrawalViewModel.kt b/app/src/main/java/com/mashup/ui/withdrawl/WithdrawalViewModel.kt
index 9479dc46..348f2d70 100644
--- a/app/src/main/java/com/mashup/ui/withdrawl/WithdrawalViewModel.kt
+++ b/app/src/main/java/com/mashup/ui/withdrawl/WithdrawalViewModel.kt
@@ -1,6 +1,6 @@
package com.mashup.ui.withdrawl
-import com.mashup.base.BaseViewModel
+import com.mashup.core.common.base.BaseViewModel
import com.mashup.core.common.model.Validation
import com.mashup.data.repository.MemberRepository
import com.mashup.datastore.data.repository.UserPreferenceRepository
diff --git a/app/src/main/res/layout/activity_danggn_info.xml b/app/src/main/res/layout/activity_danggn_info.xml
new file mode 100644
index 00000000..dce25d6c
--- /dev/null
+++ b/app/src/main/res/layout/activity_danggn_info.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_shake_danggn.xml b/app/src/main/res/layout/activity_shake_danggn.xml
new file mode 100644
index 00000000..3b98942f
--- /dev/null
+++ b/app/src/main/res/layout/activity_shake_danggn.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_schedule.xml b/app/src/main/res/layout/fragment_schedule.xml
index b441a791..4f91a58e 100644
--- a/app/src/main/res/layout/fragment_schedule.xml
+++ b/app/src/main/res/layout/fragment_schedule.xml
@@ -26,6 +26,16 @@
app:layout_constraintEnd_toEndOf="parent"
tools:text="@string/event_list_title" />
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-v27/themes.xml b/app/src/main/res/values-v27/themes.xml
new file mode 100644
index 00000000..04e678cf
--- /dev/null
+++ b/app/src/main/res/values-v27/themes.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 4514cbc2..04e678cf 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -8,6 +8,8 @@
- true
- @style/AppBottomSheetDialogTheme
+
+ - true