|
|
@ -2,19 +2,35 @@ package com.danilafe.fencelessgrazing |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
class CollarListActivity : AppCompatActivity() { |
|
|
|
|
|
|
|
private lateinit var token: String |
|
|
|
// The list of collar summaries and its list adapter. |
|
|
|
private val summaries : MutableList<CollarSummary> = mutableListOf() |
|
|
|
private lateinit var summaryAdapter: CollarSummaryAdapter |
|
|
|
|
|
|
|
// 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() |
|
|
|
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) { |
|
|
|
super.onCreate(savedInstanceState) |
|
|
@ -27,14 +43,15 @@ class CollarListActivity : AppCompatActivity() { |
|
|
|
val collarList: RecyclerView = findViewById(R.id.collarSummaryList) |
|
|
|
val layoutManager = LinearLayoutManager(collarList.context) |
|
|
|
token = intent.getStringExtra("token")!! |
|
|
|
summaryAdapter = CollarSummaryAdapter(collarList.context, getString(R.string.apiUrl), token) |
|
|
|
summaryAdapter = CollarSummaryAdapter(summaries) |
|
|
|
map = findViewById(R.id.map) |
|
|
|
map.setTileSource(TileSourceFactory.MAPNIK) |
|
|
|
queue = Volley.newRequestQueue(this) |
|
|
|
|
|
|
|
collarList.adapter = summaryAdapter |
|
|
|
collarList.layoutManager = layoutManager |
|
|
|
collarList.addItemDecoration(DividerItemDecoration(collarList.context, layoutManager.orientation)) |
|
|
|
summaryAdapter.triggerRefresh() |
|
|
|
triggerRefresh() |
|
|
|
} |
|
|
|
|
|
|
|
override fun onResume() { |
|
|
@ -47,4 +64,41 @@ class CollarListActivity : AppCompatActivity() { |
|
|
|
map.onPause() |
|
|
|
} |
|
|
|
|
|
|
|
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 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) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|