app/app/src/main/java/com/danilafe/fencelessgrazing/CollarListActivity.kt

137 lines
4.6 KiB
Kotlin

package com.danilafe.fencelessgrazing
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.RequestQueue
import com.android.volley.Response
import com.android.volley.toolbox.Volley
import com.danilafe.fencelessgrazing.model.CollarSummary
import com.danilafe.fencelessgrazing.requests.CollarRequest
import org.osmdroid.config.Configuration
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.Marker
import java.util.*
import kotlin.concurrent.timerTask
class CollarListActivity : AppCompatActivity() {
// The list of collar summaries and its list adapter.
private val summaries : MutableList<CollarSummary> = mutableListOf()
private lateinit var summaryAdapter: CollarSummaryAdapter
private lateinit var collarList: RecyclerView
// The API token and request queue.
private lateinit var token: String
private lateinit var queue: RequestQueue
// The OpenStreetMap map.
private lateinit var map: MapView
private val collarOverlays: MutableMap<Int, Marker> = mutableMapOf()
// Timer used to schedule refresh
private var refreshTimer = Timer()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Configuration.getInstance().load(applicationContext,
PreferenceManager.getDefaultSharedPreferences(applicationContext))
setContentView(R.layout.activity_collar_list)
findViews()
token = intent.getStringExtra("token")!!
map.setTileSource(TileSourceFactory.MAPNIK)
queue = Volley.newRequestQueue(this)
setupCollarList()
}
override fun onResume() {
super.onResume()
map.onResume()
refreshTimer = Timer()
refreshTimer.schedule(timerTask { triggerRefresh() }, 0L, 5000L)
}
override fun onPause() {
super.onPause()
map.onPause()
refreshTimer.cancel()
}
private fun triggerRefresh() {
val request = CollarRequest(getString(R.string.apiUrl), token,
Response.Listener {
summaries.clear()
summaries.addAll(it)
summaryAdapter.notifyDataSetChanged()
updateMapOverlay()
},
Response.ErrorListener {
Toast.makeText(this, "Failed to retrieve collar list!", Toast.LENGTH_SHORT).show()
}
)
queue.add(request)
}
private fun findViews() {
collarList = findViewById(R.id.collarSummaryList)
map = findViewById(R.id.map)
}
private fun startCollarDetailActivity(collar: CollarSummary) {
val newIntent = Intent(this, CollarDetailActivity::class.java).apply {
putExtra("token", token)
putExtra("identifier", collar.id)
}
startActivity(newIntent)
}
private fun setupCollarList() {
val layoutManager = LinearLayoutManager(collarList.context)
summaryAdapter = CollarSummaryAdapter(summaries, object : CollarClickListener {
override fun onCollarClick(collar: CollarSummary?) {
if (collar == null) return
startCollarDetailActivity(collar)
}
})
collarList.adapter = summaryAdapter
collarList.layoutManager = layoutManager
collarList.addItemDecoration(DividerItemDecoration(collarList.context, layoutManager.orientation))
refreshTimer.schedule(timerTask { triggerRefresh() }, 0L, 5000L)
}
private fun updateMapOverlay() {
val currentSet = mutableSetOf<Int>()
summaries.forEach {
// Create or update overlay
val overlay = collarOverlays[it.id] ?: Marker(map)
overlay.title = it.name
overlay.position = GeoPoint(it.pos.longitude.toDouble(), it.pos.latitude.toDouble())
// Store new / existing overlay.
if(!collarOverlays.containsKey(it.id)) map.overlays.add(overlay)
collarOverlays[it.id] = overlay
currentSet.add(it.id)
}
val previousSet = collarOverlays.keys
previousSet.forEach {
if(!currentSet.contains(it)) {
map.overlays.remove(collarOverlays[it])
collarOverlays.remove(it)
}
}
map.invalidate()
}
}