Skip to content

Commit d0e2c85

Browse files
authored
release: 0.0.3(3) 버전 배포
release: 0.0.3(3) 버전 배포
2 parents 5ce1139 + 4dd1f20 commit d0e2c85

File tree

12 files changed

+240
-88
lines changed

12 files changed

+240
-88
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ android {
1616
applicationId "com.woozoo.menumonya"
1717
minSdk 24
1818
targetSdk 33
19-
versionCode 2
20-
versionName "0.0.2"
19+
versionCode 3
20+
versionName "0.0.3"
2121

2222
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
2323
}

app/src/main/java/com/woozoo/menumonya/Application.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package com.woozoo.menumonya
22

33
import android.app.Application
44
import android.content.Context
5+
import com.woozoo.menumonya.repository.FireStoreRepository
6+
import com.woozoo.menumonya.repository.RemoteConfigRepository
57

68
class Application: Application() {
79

@@ -16,4 +18,12 @@ class Application: Application() {
1618
return instance!!.applicationContext
1719
}
1820
}
21+
22+
override fun onCreate() {
23+
super.onCreate()
24+
25+
// 종속 관계 때문에 초기화 순서 중요함
26+
RemoteConfigRepository.initialize()
27+
FireStoreRepository.initialize()
28+
}
1929
}

app/src/main/java/com/woozoo/menumonya/Constants.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ class Constants {
1212
val GLIDE_IMAGE_SIZE_WIDTH = 100
1313
val GLIDE_IMAGE_SIZE_HEIGHT = 100
1414

15-
val FEEDBACK_URL = "https://forms.gle/Emcodxf3ngNqLCHs7"
15+
val REMOTE_CONFIG_FETCH_INTERVAL: Long = 60 * 1 // 1분마다 업데이트 함
1616
}
1717
}

app/src/main/java/com/woozoo/menumonya/MainActivity.kt

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import android.Manifest
44
import android.content.Intent
55
import android.content.Intent.ACTION_VIEW
66
import android.content.pm.PackageManager
7-
import android.net.Ur
7+
import android.net.Uri
88
import android.os.Bundle
99
import android.provider.Settings
1010
import android.view.View
@@ -15,7 +15,6 @@ import androidx.appcompat.app.AppCompatActivity
1515
import androidx.recyclerview.widget.RecyclerView
1616
import androidx.viewpager2.widget.ViewPager2
1717
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
18-
import com.woozoo.menumonya.Constants.Companion.FEEDBACK_URL
1918
import com.woozoo.menumonya.MainViewModel.Event
2019
import com.woozoo.menumonya.databinding.ActivityMainBinding
2120
import com.woozoo.menumonya.util.PermissionUtils.Companion.ACCESS_FINE_LOCATION_REQUEST_CODE
@@ -86,17 +85,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
8685

8786
binding.naverMap.onCreate(savedInstanceState)
8887

89-
viewModel.initializeMapView(binding.naverMap, this)
90-
}
91-
92-
private fun updatePagerHeightForChild(view: View, pager: ViewPager2) {
93-
view.post {
94-
val wMeasureSpec = View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.EXACTLY)
95-
val hMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
96-
view.measure(wMeasureSpec, hMeasureSpec)
97-
pager.layoutParams = (pager.layoutParams).also { lp -> lp.height = view.measuredHeight }
98-
pager.invalidate()
99-
}
88+
viewModel.initializeMapView(binding.naverMap)
10089
}
10190

10291
private fun handleEvent(event: Event) = when (event) {
@@ -137,6 +126,11 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
137126
}
138127
}.create().show()
139128
}
129+
is Event.MoveToCurrentLocation -> {
130+
binding.currentLocationBtn.background = resources.getDrawable(R.drawable.current_location_button_selected)
131+
binding.currentLocationTv.setTextColor(resources.getColor(R.color.colorSecondary))
132+
binding.currentLocationIv.setColorFilter(resources.getColor(R.color.colorSecondary))
133+
}
140134
}
141135

142136
override fun onStart() {
@@ -185,6 +179,10 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
185179
binding.locationYsBtn.background = applicationContext.getDrawable(R.drawable.white_button_background)
186180
binding.locationGnBtn.setTextColor(applicationContext.getColor(R.color.white))
187181
binding.locationYsBtn.setTextColor(applicationContext.getColor(R.color.gray600))
182+
183+
binding.currentLocationBtn.background = resources.getDrawable(R.drawable.current_location_button)
184+
binding.currentLocationTv.setTextColor(resources.getColor(R.color.colorPrimary))
185+
binding.currentLocationIv.setColorFilter(resources.getColor(R.color.colorPrimary))
188186
}
189187
R.id.location_ys_btn -> {
190188
viewPager.invalidate()
@@ -195,9 +193,14 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
195193
binding.locationGnBtn.background = applicationContext.getDrawable(R.drawable.white_button_background)
196194
binding.locationYsBtn.setTextColor(applicationContext.getColor(R.color.white))
197195
binding.locationGnBtn.setTextColor(applicationContext.getColor(R.color.gray600))
196+
197+
binding.currentLocationBtn.background = resources.getDrawable(R.drawable.current_location_button)
198+
binding.currentLocationTv.setTextColor(resources.getColor(R.color.colorPrimary))
199+
binding.currentLocationIv.setColorFilter(resources.getColor(R.color.colorPrimary))
198200
}
199201
R.id.feedback_iv -> {
200-
val intent = Intent(ACTION_VIEW, Uri.parse(FEEDBACK_URL))
202+
val feedbackUrl = viewModel.getFeedbackUrl()
203+
val intent = Intent(ACTION_VIEW, Uri.parse(feedbackUrl))
201204
startActivity(intent)
202205
}
203206
// '내 주변' 버튼 클릭

app/src/main/java/com/woozoo/menumonya/MainViewModel.kt

Lines changed: 16 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ import android.location.LocationListener
88
import android.location.LocationManager
99
import androidx.lifecycle.AndroidViewModel
1010
import androidx.lifecycle.viewModelScope
11-
import com.google.firebase.firestore.ktx.firestore
12-
import com.google.firebase.firestore.ktx.toObject
13-
import com.google.firebase.ktx.Firebase
1411
import com.naver.maps.geometry.LatLng
1512
import com.naver.maps.map.*
1613
import com.naver.maps.map.overlay.Marker
@@ -21,19 +18,15 @@ import com.woozoo.menumonya.Constants.Companion.LATLNG_GN
2118
import com.woozoo.menumonya.Constants.Companion.LATLNG_YS
2219
import com.woozoo.menumonya.Constants.Companion.MAP_DEFAULT_ZOOM
2320
import com.woozoo.menumonya.Constants.Companion.MAP_MIN_ZOOM
24-
import com.woozoo.menumonya.model.Menu
2521
import com.woozoo.menumonya.model.Restaurant
26-
import com.woozoo.menumonya.util.DateUtils.Companion.getTodayDate
22+
import com.woozoo.menumonya.repository.FireStoreRepository
23+
import com.woozoo.menumonya.repository.RemoteConfigRepository
2724
import com.woozoo.menumonya.util.LocationUtils.Companion.requestLocationUpdateOnce
2825
import com.woozoo.menumonya.util.PermissionUtils.Companion.isGpsPermissionAllowed
29-
3026
import com.woozoo.menumonya.util.PermissionUtils.Companion.isLocationPermissionAllowed
31-
import kotlinx.coroutines.Deferred
32-
import kotlinx.coroutines.async
3327
import kotlinx.coroutines.flow.MutableSharedFlow
3428
import kotlinx.coroutines.flow.asSharedFlow
3529
import kotlinx.coroutines.launch
36-
import kotlinx.coroutines.tasks.await
3730
import java.lang.Double.parseDouble
3831

3932
class MainViewModel(application: Application): AndroidViewModel(Application()) {
@@ -45,6 +38,9 @@ class MainViewModel(application: Application): AndroidViewModel(Application()) {
4538
lateinit var naverMap: NaverMap
4639
private var locationManager: LocationManager
4740

41+
private var firestoreRepository = FireStoreRepository.get()
42+
private var remoteConfigRepository = RemoteConfigRepository.get()
43+
4844
private var mRestaurantInfoArray: ArrayList<Restaurant> = ArrayList()
4945
private var markerList: ArrayList<Marker> = ArrayList()
5046
private var selectedLocation: String = ""
@@ -60,13 +56,9 @@ class MainViewModel(application: Application): AndroidViewModel(Application()) {
6056
}
6157

6258
@SuppressLint("MissingPermission")
63-
fun initializeMapView(mapView: MapView, activity: Activity) {
59+
fun initializeMapView(mapView: MapView) {
6460
mapView.getMapAsync {
6561
naverMap = it.apply {
66-
// locationSource = FusedLocationSource(
67-
// activity,
68-
// LOCATION_PERMISSION_REQUEST_CODE
69-
// )
7062
locationTrackingMode = LocationTrackingMode.NoFollow
7163
uiSettings.apply {
7264
isLocationButtonEnabled = false
@@ -122,59 +114,6 @@ class MainViewModel(application: Application): AndroidViewModel(Application()) {
122114
naverMap.moveCamera(CameraUpdate.withParams(cameraUpdateParams))
123115
}
124116

125-
suspend fun getTodayRestaurantInfoAsync(location: String): Deferred<ArrayList<Restaurant>> {
126-
return viewModelScope.async {
127-
val restaurantInfo = ArrayList<Restaurant>()
128-
val db = Firebase.firestore
129-
val restaurantRef = db.collection("restaurants")
130-
val query = restaurantRef.whereArrayContainsAny("locationCategory", listOf(location))
131-
132-
val result = query.get().await()
133-
val documents = result.documents
134-
135-
for (document in documents) {
136-
val restaurant = document.toObject<Restaurant>()
137-
138-
if (restaurant != null) {
139-
// 메뉴 정보 조회
140-
val menu = getMenuAsync(document.id)?.await()
141-
142-
val todayMenu = menu?.date?.get(getTodayDate())
143-
if (todayMenu != null) restaurant.todayMenu = todayMenu
144-
145-
restaurantInfo.add(restaurant)
146-
}
147-
}
148-
149-
// locationCategoryOrder값으로 순서 재정렬(가까운 블록에 위치한 순서대로)
150-
for (restaurant in restaurantInfo) {
151-
restaurant.locationCategoryOrder.removeAll { !it.contains(location) }
152-
}
153-
restaurantInfo.sortBy { it.locationCategoryOrder[0] }
154-
155-
restaurantInfo
156-
}
157-
}
158-
159-
suspend fun getMenuAsync(restaurantId: String): Deferred<Menu>? {
160-
return viewModelScope.async {
161-
var menu = Menu()
162-
163-
val db = Firebase.firestore
164-
val menuRef = db.collection("menus")
165-
val query = menuRef.whereEqualTo("restaurantId", restaurantId)
166-
167-
val result = query.get().await()
168-
val documents = result.documents
169-
170-
if (documents.size > 0) {
171-
menu = documents[0].toObject<Menu>()!!
172-
}
173-
174-
menu
175-
}
176-
}
177-
178117
/**
179118
* 하단의 식당 정보 가로 스크롤 뷰를 표시함.
180119
* - (중요) 지도에 마커를 표시하기 위한 식당 정보를 이미 fetch하였다는 전제 하에 작동함.
@@ -194,7 +133,7 @@ class MainViewModel(application: Application): AndroidViewModel(Application()) {
194133
"역삼" -> moveCameraCoord(LATLNG_YS.latitude, LATLNG_YS.longitude)
195134
}
196135

197-
mRestaurantInfoArray = getTodayRestaurantInfoAsync(selectedLocation).await() // TODO: 정렬 안돼있음
136+
mRestaurantInfoArray = firestoreRepository.getRestaurantInLocation(location)
198137

199138
setMarkers(mRestaurantInfoArray)
200139
}
@@ -257,11 +196,16 @@ class MainViewModel(application: Application): AndroidViewModel(Application()) {
257196
locationSource = FusedLocationSource(activity, LOCATION_PERMISSION_REQUEST_CODE)
258197
locationTrackingMode = LocationTrackingMode.Follow
259198
}
199+
moveToCurrentLocation()
260200
})
261201
}
262202
}
263203
}
264204

205+
fun getFeedbackUrl(): String {
206+
return remoteConfigRepository.getFeedbackUrl()
207+
}
208+
265209
private fun showToast(text: String) {
266210
event(Event.ShowToast(text))
267211
}
@@ -281,6 +225,9 @@ class MainViewModel(application: Application): AndroidViewModel(Application()) {
281225
private fun showGpsPermissionAlert() {
282226
event(Event.ShowGpsPermissionAlert(""))
283227
}
228+
private fun moveToCurrentLocation() {
229+
event(Event.MoveToCurrentLocation(""))
230+
}
284231

285232
sealed class Event {
286233
/**
@@ -293,5 +240,6 @@ class MainViewModel(application: Application): AndroidViewModel(Application()) {
293240
data class OnMarkerClicked(val markerIndex: Int, val location: String): Event()
294241
data class RequestLocationPermission(val data: String): Event()
295242
data class ShowGpsPermissionAlert(val data: String): Event()
243+
data class MoveToCurrentLocation(val data: String): Event()
296244
}
297245
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.woozoo.menumonya.repository
2+
3+
import com.google.firebase.firestore.ktx.firestore
4+
import com.google.firebase.firestore.ktx.toObject
5+
import com.google.firebase.ktx.Firebase
6+
import com.woozoo.menumonya.model.Menu
7+
import com.woozoo.menumonya.model.Restaurant
8+
import com.woozoo.menumonya.util.DateUtils
9+
import kotlinx.coroutines.Dispatchers
10+
import kotlinx.coroutines.tasks.await
11+
import kotlinx.coroutines.withContext
12+
13+
class FireStoreRepository {
14+
private val db = Firebase.firestore
15+
private var remoteConfigRepository = RemoteConfigRepository.get()
16+
17+
private lateinit var restaurantCollectionName: String
18+
private lateinit var menuCollectionName: String
19+
20+
companion object {
21+
private var instance: FireStoreRepository? = null
22+
23+
fun initialize() {
24+
if (instance == null) {
25+
instance = FireStoreRepository()
26+
}
27+
}
28+
29+
fun get(): FireStoreRepository {
30+
return instance ?: throw java.lang.IllegalStateException("FireStoreRepository must be initialized")
31+
}
32+
}
33+
34+
suspend fun getRestaurantInLocation(location: String) = withContext(Dispatchers.IO) {
35+
restaurantCollectionName = remoteConfigRepository.getRestaurantsCollectionName()
36+
37+
val restaurantInfo = ArrayList<Restaurant>()
38+
val restaurantRef = db.collection(restaurantCollectionName)
39+
val query = restaurantRef.whereArrayContainsAny("locationCategory", listOf(location))
40+
41+
val result = query.get().await()
42+
val documents = result.documents
43+
44+
for (document in documents) {
45+
val restaurant = document.toObject<Restaurant>()
46+
47+
if (restaurant != null) {
48+
// 메뉴 정보 조회
49+
val menu = getMenu(document.id)
50+
51+
val todayMenu = menu.date.get(DateUtils.getTodayDate())
52+
if (todayMenu != null) restaurant.todayMenu = todayMenu
53+
54+
restaurantInfo.add(restaurant)
55+
}
56+
}
57+
58+
// locationCategoryOrder값으로 순서 재정렬(가까운 블록에 위치한 순서대로)
59+
for (restaurant in restaurantInfo) {
60+
restaurant.locationCategoryOrder.removeAll { !it.contains(location) }
61+
}
62+
restaurantInfo.sortBy { it.locationCategoryOrder[0] }
63+
64+
restaurantInfo
65+
}
66+
67+
suspend fun getMenu(restaurantId: String) = withContext(Dispatchers.IO) {
68+
menuCollectionName = remoteConfigRepository.getMenuCollectionName()
69+
70+
var menu = Menu()
71+
72+
val menuRef = db.collection(menuCollectionName)
73+
val query = menuRef.whereEqualTo("restaurantId", restaurantId)
74+
75+
val result = query.get().await()
76+
val documents = result.documents
77+
78+
if (documents.size > 0) {
79+
menu = documents[0].toObject<Menu>()!!
80+
}
81+
82+
menu
83+
}
84+
}

0 commit comments

Comments
 (0)