@@ -16,13 +16,18 @@ import androidx.lifecycle.Lifecycle
1616import androidx.lifecycle.LifecycleObserver
1717import androidx.lifecycle.OnLifecycleEvent
1818import androidx.lifecycle.lifecycleScope
19+ import androidx.room.Room
1920import io.flutter.embedding.engine.FlutterEngine
2021import io.flutter.plugin.common.MethodCall
2122import io.flutter.plugin.common.MethodChannel
23+ import kotlinx.coroutines.CoroutineScope
24+ import kotlinx.coroutines.Dispatchers
2225import kotlinx.coroutines.delay
2326import kotlinx.coroutines.flow.MutableStateFlow
2427import kotlinx.coroutines.flow.StateFlow
2528import kotlinx.coroutines.launch
29+ import vn.vietmap.androidauto.cache.AppCacheDatabase
30+ import vn.vietmap.androidauto.cache.PlaceItemDAO
2631import vn.vietmap.androidauto.model.PlaceItem
2732import vn.vietmap.androidauto.service.IAndroidAutoSearchCommunicator
2833import vn.vietmap.androidauto.service.SearchScreenService
@@ -34,12 +39,16 @@ import vn.vietmap.vietmapsdk.location.engine.LocationEngineResult
3439import java.lang.Exception
3540
3641class VietMapSearchScreen (carContext : CarContext ): Screen(carContext), LifecycleObserver, IAndroidAutoSearchCommunicator {
42+ private val appCacheDatabase = Room .databaseBuilder(carContext, AppCacheDatabase ::class .java, " app-cache-database" ).build()
43+ private val placeItemDAO: PlaceItemDAO
3744 private val searchScreenService : SearchScreenService = ServiceGenerator .createService(SearchScreenService ::class .java)
3845 private var locationEngine: LocationEngine ? = null
39- private var placeItems : List <PlaceItem > = emptyList ()
46+ private var placeItems : ArrayList <PlaceItem > = ArrayList ()
4047 private var searchMethodChannel: MethodChannel ? = null
4148 private var flutterEngine: FlutterEngine ? = null
4249 private var searchText: String = " "
50+ private val ioCoroutineScope : CoroutineScope = CoroutineScope (Dispatchers .IO )
51+ private val cachePlaceItems : ArrayList <PlaceItem > = ArrayList ()
4352
4453 companion object {
4554 const val VIETMAP_ANDROID_AUTO_CHANNEL = " vn.vietmap.automotive/search"
@@ -56,6 +65,10 @@ class VietMapSearchScreen(carContext: CarContext): Screen(carContext), Lifecycle
5665 lifecycle.addObserver(this )
5766 locationEngine = LocationEngineProvider .getBestLocationEngine(carContext)
5867 setSearchScreenInstance(this )
68+ placeItemDAO = appCacheDatabase.placeItemDAO()
69+ ioCoroutineScope.launch {
70+ getInitialPlaceItems()
71+ }
5972 }
6073
6174 fun initFlutterEngine (flutterEngine : FlutterEngine ){
@@ -78,7 +91,7 @@ class VietMapSearchScreen(carContext: CarContext): Screen(carContext), Lifecycle
7891 }
7992 }
8093 private fun performSearch (query : String , latLngString : String? ){
81- lifecycleScope .launch {
94+ ioCoroutineScope .launch {
8295 delay(500 )
8396 val resp = searchScreenService.autocomplete(query, latLngString)
8497 setResults(if (resp.isSuccessful) resp.body() ? : emptyList() else emptyList())
@@ -87,7 +100,10 @@ class VietMapSearchScreen(carContext: CarContext): Screen(carContext), Lifecycle
87100
88101
89102 private fun setResults (results : List <PlaceItem >){
90- placeItems = results.toList()
103+ placeItems.let {
104+ it.clear()
105+ it.addAll(results)
106+ }
91107 val itemList = ItemList .Builder ()
92108 results.forEach{
93109 itemList.addItem(
@@ -112,14 +128,59 @@ class VietMapSearchScreen(carContext: CarContext): Screen(carContext), Lifecycle
112128 private fun onPlaceSelected (placeItem : PlaceItem ){
113129 // Pop back to navigation place and set destination
114130 searchMethodChannel?.invokeMethod(" selectSearchResult" , mapOf (" refId" to placeItem.ref_id))
115- lifecycleScope .launch {
131+ ioCoroutineScope .launch {
116132 val resp = searchScreenService.getPlaceDetail(placeItem.ref_id)
117133 if (resp.isSuccessful){
134+ addPlaceItemToCache(placeItem)
118135 setResult(resp.body())
119- finish()
136+ lifecycleScope.launch {
137+ finish()
138+ }
120139 }
121140 }
122141 }
142+
143+ private fun addPlaceItemToCache (placeItem : PlaceItem ){
144+ val cachePlaceItems = placeItemDAO.getAll()
145+ if (cachePlaceItems.size >= 5 ){
146+ placeItemDAO.delete(cachePlaceItems[0 ])
147+ }
148+ cachePlaceItems.forEach {
149+ if (it.ref_id == placeItem.ref_id){
150+ placeItemDAO.delete(it)
151+ }
152+ }
153+ placeItemDAO.insertAll(placeItem)
154+ this .cachePlaceItems.let {
155+ it.clear()
156+ it.add(placeItem)
157+ }
158+ }
159+
160+ private fun getInitialPlaceItems (){
161+ cachePlaceItems.let {
162+ it.clear()
163+ it.addAll(placeItemDAO.getAll().reversed())
164+ }
165+ refreshSearchTemplate()
166+ searchTemplate.setItemList(
167+ ItemList .Builder ()
168+ .apply {
169+ cachePlaceItems.forEach {
170+ addItem(
171+ Row .Builder ()
172+ .setTitle(it.name)
173+ .setOnClickListener { onPlaceSelected(it) }
174+ .addText(it.address)
175+ .build()
176+ )
177+ }
178+ }
179+ .build()
180+ )
181+ invalidate()
182+ }
183+
123184 private var backAction = Action .Builder ()
124185 .setIcon(CarIcon .BACK )
125186 .setOnClickListener { onBackPressed() }
@@ -194,11 +255,13 @@ class VietMapSearchScreen(carContext: CarContext): Screen(carContext), Lifecycle
194255 override fun onSearchResultSelected (call : MethodCall , result : MethodChannel .Result ) {
195256 val args = call.arguments as Map <* , * >
196257 val refId = args[" refId" ] as String
197- lifecycleScope .launch {
258+ ioCoroutineScope .launch {
198259 val resp = searchScreenService.getPlaceDetail(refId)
199260 if (resp.isSuccessful){
200261 setResult(resp.body())
201- finish()
262+ lifecycleScope.launch {
263+ finish()
264+ }
202265 }
203266 }
204267 result.success(true )
0 commit comments