diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 1e39c1e5..90b98000 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -21,9 +21,9 @@ android {
applicationId = "com.eatssu.android"
minSdk = 23
targetSdk = 34
- versionCode = 1
- versionName = "2.1.0"
-
+ versionCode = 21
+ versionName = "2.1.1"
+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 50bbb7fb..ce54b951 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -32,11 +32,11 @@
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
- android:icon="@drawable/img_logo1_44"
+ android:icon="@drawable/img_logo_512"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true"
- android:roundIcon="@drawable/img_logo1_44"
+ android:roundIcon="@drawable/img_logo_512"
android:supportsRtl="true"
android:theme="@style/Theme.EatSSUAndroid"
android:usesCleartextTraffic="true"
@@ -151,14 +151,7 @@
android:name="android.app.lib_name"
android:value="" />
-
-
-
+
diff --git a/app/src/main/java/com/eatssu/android/data/repository/FirebaseRemoteConfigRepository.kt b/app/src/main/java/com/eatssu/android/data/repository/FirebaseRemoteConfigRepository.kt
index e18d3373..87e2bb18 100644
--- a/app/src/main/java/com/eatssu/android/data/repository/FirebaseRemoteConfigRepository.kt
+++ b/app/src/main/java/com/eatssu/android/data/repository/FirebaseRemoteConfigRepository.kt
@@ -2,11 +2,9 @@ package com.eatssu.android.data.repository
import com.eatssu.android.R
import com.eatssu.android.data.enums.Restaurant
-import com.eatssu.android.data.model.AndroidMessage
import com.eatssu.android.data.model.RestaurantInfo
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
-import com.google.gson.Gson
import org.json.JSONArray
import timber.log.Timber
@@ -41,25 +39,25 @@ class FirebaseRemoteConfigRepository {
}
}
- fun getAndroidMessage(): AndroidMessage {
-
- // Gson을 사용하여 JSON 문자열을 DTO로 파싱
- val serverStatus: AndroidMessage = Gson().fromJson(instance.getString("android_message"), AndroidMessage::class.java)
-
- // 파싱된 결과 확인
- println("Dialog: ${serverStatus.dialog}")
- println("Message: ${serverStatus.message}")
-
- return serverStatus
- }
-
- fun getForceUpdate(): Boolean {
- return instance.getBoolean("force_update")
- }
-
- fun getAppVersion(): String {
- return instance.getString("app_version")
- }
+// fun getAndroidMessage(): AndroidMessage {
+//
+// // Gson을 사용하여 JSON 문자열을 DTO로 파싱
+// val serverStatus: AndroidMessage = Gson().fromJson(instance.getString("android_message"), AndroidMessage::class.java)
+//
+// // 파싱된 결과 확인
+// println("Dialog: ${serverStatus.dialog}")
+// println("Message: ${serverStatus.message}")
+//
+// return serverStatus
+// }
+
+// fun getForceUpdate(): Boolean {
+// return instance.getBoolean("force_update")
+// }
+//
+// fun getAppVersion(): String {
+// return instance.getString("app_version")
+// }
fun getVersionCode(): Long {
return instance.getLong("android_version_code")
diff --git a/app/src/main/java/com/eatssu/android/data/usecase/GetAccessTokenUseCase.kt b/app/src/main/java/com/eatssu/android/data/usecase/GetAccessTokenUseCase.kt
index 87975038..f54de06b 100644
--- a/app/src/main/java/com/eatssu/android/data/usecase/GetAccessTokenUseCase.kt
+++ b/app/src/main/java/com/eatssu/android/data/usecase/GetAccessTokenUseCase.kt
@@ -1,14 +1,14 @@
package com.eatssu.android.data.usecase
-import com.eatssu.android.App
+import android.content.Context
import com.eatssu.android.util.MySharedPreferences
+import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
class GetAccessTokenUseCase @Inject constructor(
-// private val preferencesRepository: PreferencesRepository,
+ @ApplicationContext private val context: Context
) {
suspend operator fun invoke(): String {
-
- return MySharedPreferences.getAccessToken(App.appContext)
+ return MySharedPreferences.getAccessToken(context)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/eatssu/android/data/usecase/GetRefreshTokenUseCase.kt b/app/src/main/java/com/eatssu/android/data/usecase/GetRefreshTokenUseCase.kt
index aa69fbc0..635780b8 100644
--- a/app/src/main/java/com/eatssu/android/data/usecase/GetRefreshTokenUseCase.kt
+++ b/app/src/main/java/com/eatssu/android/data/usecase/GetRefreshTokenUseCase.kt
@@ -1,14 +1,15 @@
package com.eatssu.android.data.usecase
-import com.eatssu.android.App
+import android.content.Context
import com.eatssu.android.util.MySharedPreferences
+import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
class GetRefreshTokenUseCase @Inject constructor(
+ @ApplicationContext private val context: Context
// private val preferencesRepository: PreferencesRepository,
) {
suspend operator fun invoke(): String {
-
- return MySharedPreferences.getRefreshToken(App.appContext)
+ return MySharedPreferences.getRefreshToken(context)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/eatssu/android/data/usecase/GetUserEmailUseCase.kt b/app/src/main/java/com/eatssu/android/data/usecase/GetUserEmailUseCase.kt
index 1ccdf66c..5bbabb1c 100644
--- a/app/src/main/java/com/eatssu/android/data/usecase/GetUserEmailUseCase.kt
+++ b/app/src/main/java/com/eatssu/android/data/usecase/GetUserEmailUseCase.kt
@@ -1,14 +1,15 @@
package com.eatssu.android.data.usecase
-import com.eatssu.android.App
+import android.content.Context
import com.eatssu.android.util.MySharedPreferences
+import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
class GetUserEmailUseCase @Inject constructor(
-// private val preferencesRepository: PreferencesRepository,
+ @ApplicationContext private val context: Context
) {
suspend operator fun invoke(): String {
- return MySharedPreferences.getUserEmail(App.appContext)
+ return MySharedPreferences.getUserEmail(context)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/eatssu/android/data/usecase/GetUserNameUseCase.kt b/app/src/main/java/com/eatssu/android/data/usecase/GetUserNameUseCase.kt
index 5d204fdf..e85a49d9 100644
--- a/app/src/main/java/com/eatssu/android/data/usecase/GetUserNameUseCase.kt
+++ b/app/src/main/java/com/eatssu/android/data/usecase/GetUserNameUseCase.kt
@@ -1,14 +1,15 @@
package com.eatssu.android.data.usecase
-import com.eatssu.android.App
+import android.content.Context
import com.eatssu.android.util.MySharedPreferences
+import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
class GetUserNameUseCase @Inject constructor(
// private val preferencesRepository: PreferencesRepository,
+ @ApplicationContext private val context: Context
) {
suspend operator fun invoke(): String {
-
- return MySharedPreferences.getUserName(App.appContext)
+ return MySharedPreferences.getUserName(context)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/eatssu/android/data/usecase/LogoutUseCase.kt b/app/src/main/java/com/eatssu/android/data/usecase/LogoutUseCase.kt
index 4afc03de..7d1e5b7f 100644
--- a/app/src/main/java/com/eatssu/android/data/usecase/LogoutUseCase.kt
+++ b/app/src/main/java/com/eatssu/android/data/usecase/LogoutUseCase.kt
@@ -1,14 +1,16 @@
package com.eatssu.android.data.usecase
-import com.eatssu.android.App
+import android.content.Context
import com.eatssu.android.util.MySharedPreferences
+import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
class LogoutUseCase @Inject constructor(
+ @ApplicationContext private val context: Context
) {
suspend operator fun invoke() {
- MySharedPreferences.clearUser(App.appContext)
+ MySharedPreferences.clearUser(context)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/eatssu/android/data/usecase/SetAccessTokenUseCase.kt b/app/src/main/java/com/eatssu/android/data/usecase/SetAccessTokenUseCase.kt
index 0474445d..2c5e06b4 100644
--- a/app/src/main/java/com/eatssu/android/data/usecase/SetAccessTokenUseCase.kt
+++ b/app/src/main/java/com/eatssu/android/data/usecase/SetAccessTokenUseCase.kt
@@ -1,17 +1,15 @@
package com.eatssu.android.data.usecase
-import android.util.Log
-import com.eatssu.android.App
+import android.content.Context
import com.eatssu.android.util.MySharedPreferences
+import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
class SetAccessTokenUseCase @Inject constructor(
// private val preferencesRepository: PreferencesRepository,
+ @ApplicationContext private val context: Context
) {
suspend operator fun invoke(accessToken: String) {
- MySharedPreferences.setAccessToken(App.appContext, accessToken)
-
- Log.d("SetAccessTokenUseCase", accessToken)
-
+ MySharedPreferences.setAccessToken(context, accessToken)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/eatssu/android/data/usecase/SetRefreshTokenUseCase.kt b/app/src/main/java/com/eatssu/android/data/usecase/SetRefreshTokenUseCase.kt
index 0674ff1b..d8863c33 100644
--- a/app/src/main/java/com/eatssu/android/data/usecase/SetRefreshTokenUseCase.kt
+++ b/app/src/main/java/com/eatssu/android/data/usecase/SetRefreshTokenUseCase.kt
@@ -1,17 +1,15 @@
package com.eatssu.android.data.usecase
-import android.util.Log
-import com.eatssu.android.App
+import android.content.Context
import com.eatssu.android.util.MySharedPreferences
+import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
class SetRefreshTokenUseCase @Inject constructor(
// private val preferencesRepository: PreferencesRepository,
+ @ApplicationContext private val context: Context
) {
suspend operator fun invoke(refreshToken: String) {
- MySharedPreferences.setRefreshToken(App.appContext, refreshToken)
-
- Log.d("SetRefreshTokenUseCase", refreshToken)
-
+ MySharedPreferences.setRefreshToken(context, refreshToken)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/eatssu/android/data/usecase/SetUserEmailUseCase.kt b/app/src/main/java/com/eatssu/android/data/usecase/SetUserEmailUseCase.kt
index ca88a2bc..2e27b2ae 100644
--- a/app/src/main/java/com/eatssu/android/data/usecase/SetUserEmailUseCase.kt
+++ b/app/src/main/java/com/eatssu/android/data/usecase/SetUserEmailUseCase.kt
@@ -1,16 +1,14 @@
package com.eatssu.android.data.usecase
-import android.util.Log
-import com.eatssu.android.App
+import android.content.Context
import com.eatssu.android.util.MySharedPreferences
+import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
class SetUserEmailUseCase @Inject constructor(
+ @ApplicationContext private val context: Context
) {
suspend operator fun invoke(email: String) {
- MySharedPreferences.setUserEmail(App.appContext, email)
-
- Log.d("SetUserEmailUseCase", email)
-
+ MySharedPreferences.setUserEmail(context, email)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/eatssu/android/data/usecase/SetUserNameUseCase.kt b/app/src/main/java/com/eatssu/android/data/usecase/SetUserNameUseCase.kt
index b2b62c88..18e80ca7 100644
--- a/app/src/main/java/com/eatssu/android/data/usecase/SetUserNameUseCase.kt
+++ b/app/src/main/java/com/eatssu/android/data/usecase/SetUserNameUseCase.kt
@@ -1,18 +1,20 @@
package com.eatssu.android.data.usecase
-import com.eatssu.android.App
+import android.content.Context
import com.eatssu.android.base.BaseResponse
import com.eatssu.android.data.dto.request.ChangeNicknameRequest
import com.eatssu.android.data.repository.UserRepository
import com.eatssu.android.util.MySharedPreferences
+import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
class SetUserNameUseCase @Inject constructor(
private val userRepository: UserRepository,
+ @ApplicationContext private val context: Context
) {
suspend operator fun invoke(name: String): Flow> {
- MySharedPreferences.setUserName(App.appContext, name)
+ MySharedPreferences.setUserName(context, name)
//Todo 이게 최선일까? 로컬에 이름 Set과 리모트의 이름 change를 usecase를 따로 만들어야하나?
return userRepository.updateUserName(ChangeNicknameRequest(name))
diff --git a/app/src/main/java/com/eatssu/android/di/AppModule.kt b/app/src/main/java/com/eatssu/android/di/AppModule.kt
index 5b4f9e17..62988858 100644
--- a/app/src/main/java/com/eatssu/android/di/AppModule.kt
+++ b/app/src/main/java/com/eatssu/android/di/AppModule.kt
@@ -2,6 +2,7 @@ package com.eatssu.android.di
import android.app.Application
import android.content.Context
+import com.eatssu.android.data.repository.FirebaseRemoteConfigRepository
import com.eatssu.android.data.repository.PreferencesRepository
import dagger.Module
import dagger.Provides
@@ -25,4 +26,11 @@ object AppModule {
fun providePreferencesRepository(@ApplicationContext context: Context): PreferencesRepository {
return PreferencesRepository(context)
}
+
+ @Provides
+ @Singleton
+ fun provideFirebaseRemoteConfigRepository(): FirebaseRemoteConfigRepository {
+ return FirebaseRemoteConfigRepository()
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/eatssu/android/di/network/TokenInterceptor.kt b/app/src/main/java/com/eatssu/android/di/network/TokenInterceptor.kt
index 034072a6..d1583cc6 100644
--- a/app/src/main/java/com/eatssu/android/di/network/TokenInterceptor.kt
+++ b/app/src/main/java/com/eatssu/android/di/network/TokenInterceptor.kt
@@ -1,12 +1,11 @@
package com.eatssu.android.di.network
+import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
-import android.util.Log
import android.widget.Toast
-import com.eatssu.android.App
import com.eatssu.android.BuildConfig.BASE_URL
import com.eatssu.android.base.BaseResponse
import com.eatssu.android.data.dto.response.TokenResponse
@@ -18,6 +17,7 @@ import com.eatssu.android.data.usecase.SetRefreshTokenUseCase
import com.eatssu.android.ui.login.LoginActivity
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
+import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.runBlocking
import okhttp3.Interceptor
import okhttp3.Request
@@ -33,6 +33,7 @@ class TokenInterceptor @Inject constructor(
private val setAccessTokenUseCase: SetAccessTokenUseCase,
private val setRefreshTokenUseCase: SetRefreshTokenUseCase,
private val logoutUseCase: LogoutUseCase,
+ @ApplicationContext private val context: Context
) : Interceptor {
companion object {
@@ -68,7 +69,7 @@ class TokenInterceptor @Inject constructor(
val response = chain.proceed(request)
if (response.code == 401) {
- Log.d(TAG, "토큰 퉤퉤")
+ Timber.d("토큰 퉤퉤")
response.close()
try {
@@ -78,13 +79,13 @@ class TokenInterceptor @Inject constructor(
.addHeader(HEADER_AUTHORIZATION, "Bearer $refreshToken")
.build()
- Log.d(TAG, "재발급 중")
+ Timber.d("재발급 중")
val refreshTokenResponse = chain.proceed(refreshTokenRequest)
- Log.d(TAG, "refreshTokenResponse : $refreshTokenResponse")
+ Timber.d("refreshTokenResponse : $refreshTokenResponse")
if (refreshTokenResponse.isSuccessful) {
- Log.d(TAG, "재발급 성공")
+ Timber.d("재발급 성공")
val responseToken = parseRefreshTokenResponse(refreshTokenResponse)
@@ -110,7 +111,6 @@ class TokenInterceptor @Inject constructor(
Timber.e("재발급에서의 401")
Handler(Looper.getMainLooper()).post {
- val context = App.appContext
Toast.makeText(context, "토큰이 만료되어 로그아웃 됩니다.", Toast.LENGTH_SHORT).show()
val intent = Intent(context, LoginActivity::class.java) // 로그인 화면으로 이동
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
@@ -123,7 +123,6 @@ class TokenInterceptor @Inject constructor(
Timber.e("재발급 실패 $e")
Handler(Looper.getMainLooper()).post {
- val context = App.appContext
Toast.makeText(context, "토큰이 만료되어 로그아웃 됩니다.", Toast.LENGTH_SHORT).show()
val intent = Intent(context, LoginActivity::class.java) // 로그인 화면으로 이동
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
@@ -137,7 +136,6 @@ class TokenInterceptor @Inject constructor(
Timber.e("404 + 다른 유저!")
Handler(Looper.getMainLooper()).post {
- val context = App.appContext
Toast.makeText(context, "토큰이 만료되어 로그아웃 됩니다.", Toast.LENGTH_SHORT).show()
val intent = Intent(context, LoginActivity::class.java) // 로그인 화면으로 이동
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
@@ -150,7 +148,6 @@ class TokenInterceptor @Inject constructor(
Timber.e("500 + 다른 유저")
Handler(Looper.getMainLooper()).post {
- val context = App.appContext
Toast.makeText(context, "토큰이 만료되어 로그아웃 됩니다.", Toast.LENGTH_SHORT).show()
val intent = Intent(context, LoginActivity::class.java) // 로그인 화면으로 이동
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
diff --git a/app/src/main/java/com/eatssu/android/ui/info/InfoActivity.kt b/app/src/main/java/com/eatssu/android/ui/info/InfoActivity.kt
deleted file mode 100644
index de5c06d4..00000000
--- a/app/src/main/java/com/eatssu/android/ui/info/InfoActivity.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.eatssu.android.ui.info
-
-import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
-import androidx.lifecycle.ViewModelProvider
-import com.eatssu.android.R
-import com.eatssu.android.data.enums.Restaurant
-import com.eatssu.android.data.repository.FirebaseRemoteConfigRepository
-import com.eatssu.android.databinding.ActivityInfoBinding
-
-class InfoActivity : AppCompatActivity() {
-
- private lateinit var binding: ActivityInfoBinding
-
- private lateinit var infoViewModel: InfoViewModel
- private lateinit var restaurantType: Restaurant
- private lateinit var firebaseRemoteConfigRepository: FirebaseRemoteConfigRepository
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = ActivityInfoBinding.inflate(layoutInflater)
- setContentView(binding.root)
- window.setBackgroundDrawableResource(R.drawable.shape_round_corners_dialog)
-
-
- firebaseRemoteConfigRepository = FirebaseRemoteConfigRepository()
- infoViewModel = ViewModelProvider(this, InfoViewModelFactory(firebaseRemoteConfigRepository))[InfoViewModel::class.java]
-
- restaurantType = intent.getSerializableExtra("restaurantType") as Restaurant
- binding.tvName.text = restaurantType.displayName
-
- infoViewModel.infoList.observe(this) {
-
- when (restaurantType) {
- Restaurant.DODAM -> {
- binding.tvLocation.text = infoViewModel.dodamEtc.value
- binding.tvTime.text = infoViewModel.dodamTime.value
- binding.tvEtc.text = infoViewModel.dodamEtc.value
- }
-
- Restaurant.HAKSIK -> {
- binding.tvLocation.text = infoViewModel.dodamLocation.value
- binding.tvTime.text = infoViewModel.haksikTime.value
- binding.tvEtc.text = infoViewModel.haksikEtc.value
- }
-
- Restaurant.FOOD_COURT -> {
- binding.tvLocation.text = infoViewModel.foodLocation.value
- binding.tvTime.text = infoViewModel.foodTime.value
- binding.tvEtc.text = infoViewModel.foodEtc.value
- }
-
- Restaurant.SNACK_CORNER -> {
- binding.tvLocation.text = infoViewModel.snackLocation.value
- binding.tvTime.text = infoViewModel.snackTime.value
- binding.tvEtc.text = infoViewModel.snackEtc.value
- }
-
- Restaurant.DORMITORY -> {
- binding.tvLocation.text = infoViewModel.dormitoryLocation.value
- binding.tvTime.text = infoViewModel.dormitoryTime.value
- binding.tvEtc.text = infoViewModel.dormitoryEtc.value
- }
-
- else -> {}
- }
- }
- }
-}
diff --git a/app/src/main/java/com/eatssu/android/ui/info/InfoBottomSheetFragment.kt b/app/src/main/java/com/eatssu/android/ui/info/InfoBottomSheetFragment.kt
index bf583f48..9de27f41 100644
--- a/app/src/main/java/com/eatssu/android/ui/info/InfoBottomSheetFragment.kt
+++ b/app/src/main/java/com/eatssu/android/ui/info/InfoBottomSheetFragment.kt
@@ -1,117 +1,66 @@
package com.eatssu.android.ui.info
import android.os.Bundle
-import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.lifecycle.ViewModelProvider
+import androidx.fragment.app.activityViewModels
import com.bumptech.glide.Glide
import com.eatssu.android.data.enums.Restaurant
-import com.eatssu.android.data.repository.FirebaseRemoteConfigRepository
import com.eatssu.android.databinding.FragmentBottomsheetInfoBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import timber.log.Timber
class InfoBottomSheetFragment : BottomSheetDialogFragment() {
private var _binding: FragmentBottomsheetInfoBinding? = null
private val binding get() = _binding!!
- private lateinit var infoViewModel: InfoViewModel
- private lateinit var firebaseRemoteConfigRepository: FirebaseRemoteConfigRepository
-
+ private val infoViewModel: InfoViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
- ): View? {
+ ): View {
_binding = FragmentBottomsheetInfoBinding.inflate(inflater, container, false)
-
- firebaseRemoteConfigRepository = FirebaseRemoteConfigRepository()
- infoViewModel = ViewModelProvider(
- this,
- InfoViewModelFactory(firebaseRemoteConfigRepository)
- )[InfoViewModel::class.java]
-
return binding.root
}
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- // 전달된 데이터 받기
+ // Retrieve passed data
val name = arguments?.getString("name")
val restaurantType = enumValues().find { it.name == name } ?: Restaurant.HAKSIK
- Log.d("InfoBottomSheetFragment", "onViewCreated: $name $restaurantType")
+ Timber.d("onViewCreated: $name $restaurantType")
binding.tvName.text = restaurantType.displayName
- //TODO 방법 개선
- infoViewModel.infoList.observe(this) {
+ // Collect the infoList Flow
+ CoroutineScope(Dispatchers.Main).launch {
+ infoViewModel.infoList.collect { restaurantInfoList ->
+ val restaurantInfo = infoViewModel.getRestaurantInfo(restaurantType)
- when (restaurantType) {
- Restaurant.DODAM -> {
- binding.tvLocation.text = infoViewModel.dodamLocation.value
- binding.tvTime.text = infoViewModel.dodamTime.value
- binding.tvEtc.text = infoViewModel.dodamEtc.value
+ restaurantInfo?.let {
+ binding.tvLocation.text = it.location
+ binding.tvTime.text = it.time
+ binding.tvEtc.text = it.etc
- Glide.with(this)
- .load(infoViewModel.dodamPhotoUrl.value)
+ Glide.with(this@InfoBottomSheetFragment)
+ .load(it.photoUrl)
.into(binding.ivCafeteriaPhoto)
}
-
- Restaurant.HAKSIK -> {
- binding.tvLocation.text = infoViewModel.haksikLocation.value
- binding.tvTime.text = infoViewModel.haksikTime.value
- binding.tvEtc.text = infoViewModel.haksikEtc.value
-
- Glide.with(this)
- .load(infoViewModel.haksikPhotoUrl.value)
- .into(binding.ivCafeteriaPhoto)
- }
-
- Restaurant.FOOD_COURT -> {
- binding.tvLocation.text = infoViewModel.foodLocation.value
- binding.tvTime.text = infoViewModel.foodTime.value
- binding.tvEtc.text = infoViewModel.foodEtc.value
-
- Glide.with(this)
- .load(infoViewModel.foodPhotoUrl.value)
- .into(binding.ivCafeteriaPhoto)
- }
-
- Restaurant.SNACK_CORNER -> {
- binding.tvLocation.text = infoViewModel.snackLocation.value
- binding.tvTime.text = infoViewModel.snackTime.value
- binding.tvEtc.text = infoViewModel.snackEtc.value
-
- Glide.with(this)
- .load(infoViewModel.snackPhotoUrl.value)
- .into(binding.ivCafeteriaPhoto)
- }
-
- Restaurant.DORMITORY -> {
- binding.tvLocation.text = infoViewModel.dormitoryLocation.value
- binding.tvTime.text = infoViewModel.dormitoryTime.value
- binding.tvEtc.text = infoViewModel.dormitoryEtc.value
-
- Glide.with(this)
- .load(infoViewModel.dormitoryPhotoUrl.value)
- .into(binding.ivCafeteriaPhoto)
- }
-
- else -> {}
}
}
}
companion object {
- // newInstance 메서드를 통해 데이터를 전달하는 방법
fun newInstance(data: String): InfoBottomSheetFragment {
val fragment = InfoBottomSheetFragment()
- val args = Bundle()
- args.putString("name", data)
+ val args = Bundle().apply { putString("name", data) }
fragment.arguments = args
return fragment
}
diff --git a/app/src/main/java/com/eatssu/android/ui/info/InfoViewModel.kt b/app/src/main/java/com/eatssu/android/ui/info/InfoViewModel.kt
index 84598b55..b9f1f130 100644
--- a/app/src/main/java/com/eatssu/android/ui/info/InfoViewModel.kt
+++ b/app/src/main/java/com/eatssu/android/ui/info/InfoViewModel.kt
@@ -1,73 +1,40 @@
package com.eatssu.android.ui.info
import android.util.Log
-import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.eatssu.android.data.enums.Restaurant
import com.eatssu.android.data.model.RestaurantInfo
import com.eatssu.android.data.repository.FirebaseRemoteConfigRepository
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import javax.inject.Inject
-class InfoViewModel(firebaseRemoteConfigRepository: FirebaseRemoteConfigRepository): ViewModel() {
+@HiltViewModel
+class InfoViewModel @Inject constructor(
+ private val firebaseRemoteConfigRepository: FirebaseRemoteConfigRepository
+) : ViewModel() {
- val infoList: MutableLiveData> = MutableLiveData()
+ // StateFlow to hold restaurant info list
+ private val _infoList = MutableStateFlow>(emptyList())
+ val infoList: StateFlow> = _infoList.asStateFlow()
- val dodamLocation = MutableLiveData()
- val dodamPhotoUrl = MutableLiveData()
- val dodamTime = MutableLiveData()
- val dodamEtc = MutableLiveData()
-
- val foodLocation = MutableLiveData()
- val foodPhotoUrl = MutableLiveData()
- val foodTime = MutableLiveData()
- val foodEtc = MutableLiveData()
-
- val dormitoryLocation = MutableLiveData()
- val dormitoryPhotoUrl = MutableLiveData()
- val dormitoryTime = MutableLiveData()
- val dormitoryEtc = MutableLiveData()
-
- val snackLocation = MutableLiveData()
- val snackPhotoUrl = MutableLiveData()
- val snackTime = MutableLiveData()
- val snackEtc = MutableLiveData()
-
- val haksikLocation = MutableLiveData()
- val haksikPhotoUrl = MutableLiveData()
- val haksikTime = MutableLiveData()
- val haksikEtc = MutableLiveData()
+ // Map to hold restaurant info
+ private val restaurantInfoMap: MutableMap = mutableMapOf()
init {
- infoList.value = firebaseRemoteConfigRepository.getCafeteriaInfo()
- Log.d("InfoViewModel",infoList.value.toString())
- val dodam = infoList.value!!.find { it.enum == Restaurant.DODAM }
- dodamPhotoUrl.value = dodam?.photoUrl ?: ""
- dodamTime.value = dodam?.time ?: ""
- dodamLocation.value = dodam?.location ?: ""
- dodamEtc.value = dodam?.etc ?: ""
-
- val food = infoList.value!!.find { it.enum == Restaurant.FOOD_COURT }
- foodPhotoUrl.value = food?.photoUrl ?: ""
- foodTime.value = food?.time ?: ""
- foodLocation.value = food?.location ?: ""
- foodEtc.value = food?.etc ?: ""
-
- val dormitory = infoList.value!!.find { it.enum == Restaurant.DORMITORY }
- dormitoryPhotoUrl.value = dormitory?.photoUrl ?: ""
- dormitoryTime.value = dormitory?.time ?: ""
- dormitoryLocation.value = dormitory?.location ?: ""
- dormitoryEtc.value = dormitory?.etc ?: ""
-
- val snack = infoList.value!!.find { it.enum == Restaurant.SNACK_CORNER }
- snackPhotoUrl.value = snack?.photoUrl ?: ""
- snackTime.value = snack?.time ?: ""
- snackLocation.value = snack?.location ?: ""
- snackEtc.value = snack?.etc ?: ""
+ // Load cafeteria info from repository and update the StateFlow
+ _infoList.value = firebaseRemoteConfigRepository.getCafeteriaInfo()
+ Log.d("InfoViewModel", _infoList.value.toString())
+ _infoList.value.forEach { restaurantInfo ->
+ restaurantInfoMap[restaurantInfo.enum] = restaurantInfo
+ }
+ }
- val haksik = infoList.value!!.find { it.enum == Restaurant.HAKSIK }
- haksikPhotoUrl.value = haksik?.photoUrl ?: ""
- haksikTime.value = haksik?.time ?: ""
- haksikLocation.value = haksik?.location ?: ""
- haksikEtc.value = haksik?.etc ?: ""
+ // Helper function to get restaurant details
+ fun getRestaurantInfo(restaurant: Restaurant): RestaurantInfo? {
+ return restaurantInfoMap[restaurant]
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/eatssu/android/ui/info/InfoViewModelFactory.kt b/app/src/main/java/com/eatssu/android/ui/info/InfoViewModelFactory.kt
deleted file mode 100644
index 1b982232..00000000
--- a/app/src/main/java/com/eatssu/android/ui/info/InfoViewModelFactory.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.eatssu.android.ui.info
-
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
-import com.eatssu.android.data.repository.FirebaseRemoteConfigRepository
-
-class InfoViewModelFactory(private val repository: FirebaseRemoteConfigRepository) :
- ViewModelProvider.Factory {
-
- override fun create(modelClass: Class): T {
- if (modelClass.isAssignableFrom(InfoViewModel::class.java)) {
- @Suppress("UNCHECKED_CAST")
- return InfoViewModel(repository) as T
- }
- throw IllegalArgumentException("Unknown ViewModel class")
- }
-}
-
diff --git a/app/src/main/java/com/eatssu/android/ui/login/LoginViewModel.kt b/app/src/main/java/com/eatssu/android/ui/login/LoginViewModel.kt
index 8366b4be..435399ec 100644
--- a/app/src/main/java/com/eatssu/android/ui/login/LoginViewModel.kt
+++ b/app/src/main/java/com/eatssu/android/ui/login/LoginViewModel.kt
@@ -1,8 +1,8 @@
package com.eatssu.android.ui.login
+import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.eatssu.android.App
import com.eatssu.android.R
import com.eatssu.android.data.dto.request.LoginWithKakaoRequest
import com.eatssu.android.data.usecase.LoginUseCase
@@ -10,6 +10,7 @@ import com.eatssu.android.data.usecase.SetAccessTokenUseCase
import com.eatssu.android.data.usecase.SetRefreshTokenUseCase
import com.eatssu.android.data.usecase.SetUserEmailUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
+import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -28,6 +29,7 @@ class LoginViewModel @Inject constructor(
private val setAccessTokenUseCase: SetAccessTokenUseCase,
private val setRefreshTokenUseCase: SetRefreshTokenUseCase,
private val setUserEmailUseCase: SetUserEmailUseCase,
+ @ApplicationContext private val context: Context
) : ViewModel() {
private val _uiState: MutableStateFlow = MutableStateFlow(LoginState())
@@ -46,7 +48,7 @@ class LoginViewModel @Inject constructor(
_uiState.update {
it.copy(
loading = false, error = false,
- toastMessage = App.appContext.getString(R.string.login_done)
+ toastMessage = context.getString(R.string.login_done)
)
//Todo 로그인과 회원가입에 따른 토스트 메시지 구분하기
}
diff --git a/app/src/main/java/com/eatssu/android/ui/main/MainViewModel.kt b/app/src/main/java/com/eatssu/android/ui/main/MainViewModel.kt
index 16571d76..07acdaad 100644
--- a/app/src/main/java/com/eatssu/android/ui/main/MainViewModel.kt
+++ b/app/src/main/java/com/eatssu/android/ui/main/MainViewModel.kt
@@ -1,11 +1,12 @@
package com.eatssu.android.ui.main
+import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.eatssu.android.App
import com.eatssu.android.R
import com.eatssu.android.data.usecase.GetUserInfoUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
+import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -21,6 +22,7 @@ import javax.inject.Inject
@HiltViewModel
class MainViewModel @Inject constructor(
private val getUserInfoUseCase: GetUserInfoUseCase,
+ @ApplicationContext private val context: Context
) : ViewModel() {
private val _uiState: MutableStateFlow = MutableStateFlow(MainState())
@@ -40,7 +42,7 @@ class MainViewModel @Inject constructor(
_uiState.update {
it.copy(
error = true,
- toastMessage = App.appContext.getString(R.string.not_found)
+ toastMessage = context.getString(R.string.not_found)
)
}
Timber.e(e.toString())
@@ -51,7 +53,7 @@ class MainViewModel @Inject constructor(
_uiState.update {
it.copy(
isNicknameNull = true,
- toastMessage = App.appContext.getString(R.string.set_nickname)
+ toastMessage = context.getString(R.string.set_nickname)
)
}
} else {
@@ -59,7 +61,7 @@ class MainViewModel @Inject constructor(
it.copy(
isNicknameNull = false,
toastMessage = String.format(
- App.appContext.getString(R.string.hello_user),
+ context.getString(R.string.hello_user),
this.nickname
)
)
diff --git a/app/src/main/java/com/eatssu/android/ui/main/menu/MenuAdapter.kt b/app/src/main/java/com/eatssu/android/ui/main/menu/MenuAdapter.kt
index da7f67e6..a7e0c34a 100644
--- a/app/src/main/java/com/eatssu/android/ui/main/menu/MenuAdapter.kt
+++ b/app/src/main/java/com/eatssu/android/ui/main/menu/MenuAdapter.kt
@@ -27,8 +27,7 @@ class MenuAdapter(
sectionModel: Section
) {
-
- binding.btnInfo.setOnClickListener {
+ binding.llCafeteriaInfo.setOnClickListener {
val modalBottomSheet =
InfoBottomSheetFragment.newInstance(sectionModel.cafeteria.name)
diff --git a/app/src/main/java/com/eatssu/android/ui/main/menu/MenuFragment.kt b/app/src/main/java/com/eatssu/android/ui/main/menu/MenuFragment.kt
index 9a96b5df..09686888 100644
--- a/app/src/main/java/com/eatssu/android/ui/main/menu/MenuFragment.kt
+++ b/app/src/main/java/com/eatssu/android/ui/main/menu/MenuFragment.kt
@@ -8,6 +8,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
@@ -17,12 +18,10 @@ import com.eatssu.android.data.enums.MenuType
import com.eatssu.android.data.enums.Restaurant
import com.eatssu.android.data.enums.Time
import com.eatssu.android.data.model.Section
-import com.eatssu.android.data.repository.FirebaseRemoteConfigRepository
import com.eatssu.android.data.service.MealService
import com.eatssu.android.data.service.MenuService
import com.eatssu.android.databinding.FragmentMenuBinding
import com.eatssu.android.ui.info.InfoViewModel
-import com.eatssu.android.ui.info.InfoViewModelFactory
import com.eatssu.android.ui.main.calendar.CalendarViewModel
import com.eatssu.android.util.RetrofitImpl
import java.time.DayOfWeek
@@ -51,9 +50,9 @@ class MenuFragment : Fragment() {
private val totalMenuList = ArrayList()
- private lateinit var infoViewModel: InfoViewModel
private lateinit var restaurantType: Restaurant
- private lateinit var firebaseRemoteConfigRepository: FirebaseRemoteConfigRepository
+
+ private val infoViewModel: InfoViewModel by activityViewModels()
companion object {
@@ -75,13 +74,6 @@ class MenuFragment : Fragment() {
savedInstanceState: Bundle?,
): View {
_binding = FragmentMenuBinding.inflate(inflater, container, false)
-
- firebaseRemoteConfigRepository = FirebaseRemoteConfigRepository()
- infoViewModel = ViewModelProvider(
- this,
- InfoViewModelFactory(firebaseRemoteConfigRepository)
- )[InfoViewModel::class.java]
-
return binding.root
}
@@ -92,11 +84,6 @@ class MenuFragment : Fragment() {
observeViewModel()
}
- override fun onResume() {
- super.onResume()
-
- }
-
@RequiresApi(Build.VERSION_CODES.O)
fun observeViewModel() {
menuService = RetrofitImpl.retrofit.create(MenuService::class.java)
@@ -145,7 +132,8 @@ class MenuFragment : Fragment() {
MenuType.FIXED,
Restaurant.FOOD_COURT,
result.mapFixedMenuResponseToMenu(),
- infoViewModel.foodLocation.value.toString()
+ infoViewModel.getRestaurantInfo(Restaurant.FOOD_COURT)?.location
+ ?: ""
)
)
}
@@ -163,7 +151,8 @@ class MenuFragment : Fragment() {
MenuType.FIXED,
Restaurant.SNACK_CORNER,
result.mapFixedMenuResponseToMenu(),
- infoViewModel.snackLocation.value.toString()
+ infoViewModel.getRestaurantInfo(Restaurant.SNACK_CORNER)?.location
+ ?: ""
)
)
}
@@ -198,7 +187,7 @@ class MenuFragment : Fragment() {
MenuType.VARIABLE,
Restaurant.HAKSIK,
result.mapTodayMenuResponseToMenu(),
- infoViewModel.haksikLocation.value.toString()
+ infoViewModel.getRestaurantInfo(Restaurant.HAKSIK)?.location ?: ""
)
)
@@ -217,7 +206,7 @@ class MenuFragment : Fragment() {
MenuType.VARIABLE,
Restaurant.DODAM,
result.mapTodayMenuResponseToMenu(),
- infoViewModel.dodamLocation.value.toString()
+ infoViewModel.getRestaurantInfo(Restaurant.DODAM)?.location ?: ""
)
)
}
@@ -234,7 +223,7 @@ class MenuFragment : Fragment() {
MenuType.VARIABLE,
Restaurant.DORMITORY,
result.mapTodayMenuResponseToMenu(),
- infoViewModel.dormitoryLocation.value.toString()
+ infoViewModel.getRestaurantInfo(Restaurant.DORMITORY)?.location ?: ""
)
)
}
diff --git a/app/src/main/res/drawable/img_logo_512.png b/app/src/main/res/drawable/img_logo_512.png
new file mode 100644
index 00000000..e70b5170
Binary files /dev/null and b/app/src/main/res/drawable/img_logo_512.png differ
diff --git a/app/src/main/res/layout/item_cafeteria_section.xml b/app/src/main/res/layout/item_cafeteria_section.xml
index 96912697..1bc900e1 100644
--- a/app/src/main/res/layout/item_cafeteria_section.xml
+++ b/app/src/main/res/layout/item_cafeteria_section.xml
@@ -31,6 +31,13 @@
android:text="@string/student_cafeteria"
android:textColor="@color/black" />
+
+
+
+
+
diff --git a/app/src/main/res/xml/firebase_remote_config.xml b/app/src/main/res/xml/firebase_remote_config.xml
index 148997e5..af102769 100644
--- a/app/src/main/res/xml/firebase_remote_config.xml
+++ b/app/src/main/res/xml/firebase_remote_config.xml
@@ -18,6 +18,7 @@
cafeteria_information
+ [
{
"enum": "DODAM",
"name": "도담 식당",
@@ -25,17 +26,16 @@
"time": "11:20~14:00(점심)\n17:00~18:30(저녁)",
"etc": "2개 코너 운영\n대면 배식,웰빙코너\n토요일 11:30~13:30",
"image":
- "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/04f266a1-0649-430c-af8f-29e83e87472120240823074119%E1%84%83%E1%85%A9%E1%84%83%E1%85%A1%E1%86%B7%E1%84%89%E1%85%B5%E1%86%A8%E1%84%83%E1%85%A1%E1%86%BC.jpeg"
+ "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/298437cb-45b1-48cf-bace-ea84e8f23e1820240926041857%E1%84%83%E1%85%A9%E1%84%83%E1%85%A1%E1%86%B7IMG_8268%20%E1%84%8F%E1%85%B3%E1%84%80%E1%85%A6.jpeg"
},
{
"enum": "HAKSIK",
"name": "학생 식당",
"location": "학생회관 3층",
- "time": "08:10~09:20(천원의 아침밥, 100개 한정,
- 24.03.11~06.14)\n11:20~14:00\n(점심)\n14:00~17:00(공간 개방)",
+ "time": "08:10~09:20(천원의 아침밥, 100개 한정)\n11:20~14:00\n(점심)\n14:00~17:00(공간 개방)",
"etc": "3개 코너 운영\n뚝배기찌개, 덮밥, 양식",
"image":
- "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/f0fbf458-5f7e-49bb-97e7-c663c4ec8cc820240823074519%E1%84%92%E1%85%A1%E1%86%A8%E1%84%89%E1%85%A2%E1%86%BC%E1%84%89%E1%85%B5%E1%86%A8%E1%84%83%E1%85%A1%E1%86%BC.jpeg"
+ "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/fa802164-621d-4b6d-b44e-e9de4bab225520240926041948%E1%84%92%E1%85%A1%E1%86%A8%E1%84%89%E1%85%A2%E1%86%BC%20IMG_0394%20%E1%84%8F%E1%85%B3%E1%84%80%E1%85%A6.jpeg"
},
{
"enum": "SNACK_CORNER",
@@ -53,7 +53,7 @@
"time": "휴무",
"etc": "준비 중",
"image":
- "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/2f8a9ae2-c2f9-4f20-bafe-28e0a9e414e320240823074451%E1%84%91%E1%85%AE%E1%84%83%E1%85%B3%E1%84%8F%E1%85%A9%E1%84%90%E1%85%B3.jpeg"
+ "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/09b487f5-e431-4ab2-a339-76e472ea8d8320240926041925%E1%84%91%E1%85%AE%E1%84%8F%E1%85%A9IMG_0396%20%E1%84%8F%E1%85%B3%E1%84%80%E1%85%A6.jpeg"
},
{
"enum": "DORMITORY",
@@ -62,8 +62,9 @@
"time": "08:00~09:30\n11:00~14:00\n17:00~18:30",
"etc": "주말 조식은 운영되지 않습니다.",
"image":
- "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/2f8a9ae2-c2f9-4f20-bafe-28e0a9e414e320240823074451%E1%84%91%E1%85%AE%E1%84%83%E1%85%B3%E1%84%8F%E1%85%A9%E1%84%90%E1%85%B3.jpeg"
+ "https://eatssu-prod-bucket.s3.ap-northeast-2.amazonaws.com/reviewImg/364077d5-f09b-4e9c-b5e4-e1e08d098f1820240926041231%E1%84%80%E1%85%B5%E1%84%89%E1%85%AE%E1%86%A8%E1%84%89%E1%85%A1IMG_2480%20%E1%84%8F%E1%85%B3%E1%84%80%E1%85%A6.jpeg"
}
+ ]