Bimba.git

ref: 2919df3a7321d4e904d6ed9cdd1c3c8c32a5ef6c

app/src/main/java/ml/adamsprogs/bimba/search/ResultsActivity.kt


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package ml.adamsprogs.bimba.search

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.openlocationcode.OpenLocationCode
import kotlinx.coroutines.*
import ml.adamsprogs.bimba.departures.DeparturesActivity
import ml.adamsprogs.bimba.api.*
import ml.adamsprogs.bimba.databinding.ActivityResultsBinding
import java.io.InputStream

@SuppressLint("MissingPermission")
class ResultsActivity : AppCompatActivity(), LocationListener {
	enum class Mode {
		MODE_LOCATION, MODE_SEARCH
	}

	private var _binding: ActivityResultsBinding? = null

	private val binding get() = _binding!!

	private lateinit var adapter: BimbaResultsAdapter

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		_binding = ActivityResultsBinding.inflate(layoutInflater)
		setContentView(binding.root)
		binding.resultsRecycler.layoutManager = LinearLayoutManager(this)
		adapter = BimbaResultsAdapter(layoutInflater, this, listOf()) {
			when (it) {
				is Stop -> {
					val intent = Intent(this, DeparturesActivity::class.java).apply {
						putExtra("code", it.code)
						putExtra("name", it.name)
						// todo line, date, etc
					}
					startActivity(intent)
				}
				is Line -> {
					TODO("start line graph actvity")
				}
			}
		}
		binding.resultsRecycler.adapter = adapter
		setSupportActionBar(binding.topAppBar)

		WindowCompat.setDecorFitsSystemWindows(window, false)

		when (intent.extras?.get("mode")) {
			Mode.MODE_LOCATION -> {
				supportActionBar?.title = "Stops nearby"
				locate()
			}
			Mode.MODE_SEARCH -> {
				val query = intent.extras?.getString("query")!!
				supportActionBar?.title = "Results for ‘$query"
				getItemsByQuery(query)
			}
		}
	}

	private fun locate() {  // todo also on back to this activity (onRestart?)
		val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
		locationManager.requestLocationUpdates(
			LocationManager.GPS_PROVIDER, 5000, 10f, this
		)
		locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
			?.let { onLocationChanged(it) }
	}

	override fun onLocationChanged(location: Location) {
		Log.v("Location", "found $location")
		val code = OpenLocationCode.encode(location.latitude, location.longitude)
		val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
		locationManager.removeUpdates(this)
		getItemsByLocation(code)
	}

	override fun onDestroy() {  // todo also on hide this activity (onPause?)
		super.onDestroy()
		val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
		locationManager.removeUpdates(this)
	}

	private fun getItemsByQuery(query: String) {
		MainScope().launch {
			val itemsStream = queryItems(query)
			if (itemsStream == null) {
				// todo show empty state
			} else {
				updateItems(unmarshallItemResponse(itemsStream))
			}
			Log.v("RESPONSE", "getItemsByQuery")
		}
	}

	private fun getItemsByLocation(plusCode: String) {
		Log.v("RESPONSE", "getting ItemsByLocation")
		MainScope().launch {
			val itemsStream = locateItems(plusCode)
			if (itemsStream == null) {
				// todo show empty state
			} else {
				updateItems(unmarshallItemResponse(itemsStream))
			}
			Log.v("RESPONSE", "getItemsByLocation")
		}
	}

	private fun updateItems(items: List<Item>) {
		binding.resultsProgress.visibility = View.GONE
		binding.resultsRecycler.visibility = View.VISIBLE
		adapter.update(items)
	}

	private suspend fun unmarshallItemResponse(stream: InputStream): List<Item> {
		return withContext(Dispatchers.IO) {
			when (val response = ItemsResponse.unmarshall(stream)) {
				is ItemsSuccess -> {
					return@withContext response.items
				}
				else -> {
					TODO("Error response")
				}
			}
		}
	}

}