|
|
|
|
@ -1,36 +1,209 @@ |
|
|
|
|
package net.pokeranalytics.android.ui.fragment |
|
|
|
|
|
|
|
|
|
import net.pokeranalytics.android.exceptions.TypeException |
|
|
|
|
import android.os.Bundle |
|
|
|
|
import android.view.View |
|
|
|
|
import com.google.android.libraries.places.api.model.PlaceLikelihood |
|
|
|
|
import net.pokeranalytics.android.R |
|
|
|
|
import net.pokeranalytics.android.model.realm.Location |
|
|
|
|
import net.pokeranalytics.android.ui.helpers.PlacePickerManager |
|
|
|
|
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource |
|
|
|
|
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource |
|
|
|
|
import net.pokeranalytics.android.ui.view.RowRepresentable |
|
|
|
|
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor |
|
|
|
|
import net.pokeranalytics.android.ui.view.RowViewType |
|
|
|
|
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable |
|
|
|
|
import net.pokeranalytics.android.ui.view.rowrepresentable.LocationRow |
|
|
|
|
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow |
|
|
|
|
import timber.log.Timber |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Custom EditableDataFragment to manage the LOCATE_ME case |
|
|
|
|
*/ |
|
|
|
|
class LocationDataFragment: EditableDataFragment() { |
|
|
|
|
class LocationDataFragment : EditableDataFragment(), StaticRowRepresentableDataSource { |
|
|
|
|
|
|
|
|
|
// Return the item as a Location object |
|
|
|
|
private val location: Location |
|
|
|
|
get() { |
|
|
|
|
return this.item as Location |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Loader boolean |
|
|
|
|
private var isLookingForPlaces: Boolean = false |
|
|
|
|
private var placesForRows: HashMap<CustomizableRowRepresentable, PlaceLikelihood> = HashMap() |
|
|
|
|
private var rowPlaces: ArrayList<CustomizableRowRepresentable> = ArrayList() |
|
|
|
|
private var locationActivated = false |
|
|
|
|
|
|
|
|
|
val rows = ArrayList<RowRepresentable>() |
|
|
|
|
|
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
|
|
|
|
super.onViewCreated(view, savedInstanceState) |
|
|
|
|
|
|
|
|
|
shouldOpenKeyboard = false |
|
|
|
|
locationActivated = parentActivity.hasLocationPermissionGranted() |
|
|
|
|
|
|
|
|
|
if (isUpdating) { |
|
|
|
|
|
|
|
|
|
// If we update a location, we set the switch to the correct value |
|
|
|
|
locationActivated = location.latitude != null && location.longitude != null |
|
|
|
|
|
|
|
|
|
} else if (locationActivated) { |
|
|
|
|
|
|
|
|
|
// If we create a new location, we try to locate the user by default |
|
|
|
|
isLookingForPlaces = true |
|
|
|
|
getSuggestionsPlaces() |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
updateAdapterUI() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun getDataSource(): RowRepresentableDataSource { |
|
|
|
|
return this |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun adapterRows(): List<RowRepresentable>? { |
|
|
|
|
return rows |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun stringForRow(row: RowRepresentable): String { |
|
|
|
|
return when (row) { |
|
|
|
|
SimpleRow.NAME -> location.name |
|
|
|
|
else -> return super.stringForRow(row) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun boolForRow(row: RowRepresentable): Boolean { |
|
|
|
|
return when (row) { |
|
|
|
|
LocationRow.LOCATION_PERMISSION_SWITCH -> return locationActivated |
|
|
|
|
else -> super.boolForRow(row) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor> { |
|
|
|
|
val data = java.util.ArrayList<RowRepresentableEditDescriptor>() |
|
|
|
|
when (row) { |
|
|
|
|
SimpleRow.NAME -> data.add( |
|
|
|
|
RowRepresentableEditDescriptor( |
|
|
|
|
location.name, |
|
|
|
|
SimpleRow.NAME.resId |
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
return data |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { |
|
|
|
|
when(row) { |
|
|
|
|
LocationRow.LOCATE_ME -> { |
|
|
|
|
if (item is Location) { |
|
|
|
|
(item as Location).isLookingForPlaces = true |
|
|
|
|
PlacePickerManager.create(parentActivity, row, this) |
|
|
|
|
rowRepresentableAdapter.refreshRow(row) |
|
|
|
|
} else { |
|
|
|
|
throw TypeException("Need to manage LocationRow.LOCATE_ME for ${item::class.java}") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else -> super.onRowSelected(position, row, fromAction) |
|
|
|
|
// If we click on a location row, save the location (and finish activity) |
|
|
|
|
placesForRows[row]?.place?.let { place -> |
|
|
|
|
location.setPlace(place) |
|
|
|
|
saveData() |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
super.onRowSelected(position, row, fromAction) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun onRowValueChanged(value: Any?, row: RowRepresentable) { |
|
|
|
|
super.onRowValueChanged(value, row) |
|
|
|
|
when (row) { |
|
|
|
|
LocationRow.LOCATE_ME -> { |
|
|
|
|
rowRepresentableAdapter.notifyDataSetChanged() |
|
|
|
|
LocationRow.LOCATION_PERMISSION_SWITCH -> { |
|
|
|
|
if (value is Boolean && value != locationActivated) { |
|
|
|
|
rowPlaces.clear() |
|
|
|
|
locationActivated = value |
|
|
|
|
isLookingForPlaces = value |
|
|
|
|
if (value) { |
|
|
|
|
updateAdapterUI() |
|
|
|
|
getSuggestionsPlaces() |
|
|
|
|
} else { |
|
|
|
|
clearCurrentLocation() |
|
|
|
|
updateAdapterUI() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else -> super.onRowValueChanged(value, row) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Clear current location |
|
|
|
|
*/ |
|
|
|
|
private fun clearCurrentLocation() { |
|
|
|
|
location.latitude = null |
|
|
|
|
location.longitude = null |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Refresh rows |
|
|
|
|
*/ |
|
|
|
|
private fun refreshRows() { |
|
|
|
|
rows.clear() |
|
|
|
|
rows.add(SimpleRow.NAME) |
|
|
|
|
rows.add(LocationRow.LOCATION_PERMISSION_SWITCH) |
|
|
|
|
|
|
|
|
|
if (isLookingForPlaces) { |
|
|
|
|
rows.add(LocationRow.LOCATION_LOADER) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (locationActivated && rowPlaces.size > 0) { |
|
|
|
|
rows.add(CustomizableRowRepresentable(resId = R.string.suggestions)) |
|
|
|
|
for (row in rowPlaces) { |
|
|
|
|
rows.add(row) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Update UI adapter |
|
|
|
|
*/ |
|
|
|
|
private fun updateAdapterUI() { |
|
|
|
|
|
|
|
|
|
val currentRowsSize = rows.size |
|
|
|
|
refreshRows() |
|
|
|
|
val newRowsSize = rows.size |
|
|
|
|
|
|
|
|
|
if (currentRowsSize < newRowsSize) { |
|
|
|
|
rowRepresentableAdapter.notifyItemRangeInserted(currentRowsSize, newRowsSize - currentRowsSize) |
|
|
|
|
} else { |
|
|
|
|
rowRepresentableAdapter.notifyItemRangeRemoved(newRowsSize, currentRowsSize - newRowsSize) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Return the places around the user |
|
|
|
|
*/ |
|
|
|
|
private fun getSuggestionsPlaces() { |
|
|
|
|
|
|
|
|
|
val maxResults = 5 |
|
|
|
|
|
|
|
|
|
parentActivity.askForPlacesRequest { success, places -> |
|
|
|
|
|
|
|
|
|
if (success) { |
|
|
|
|
// Try to get the location of the user |
|
|
|
|
parentActivity.findCurrentLocation {currentLocation -> |
|
|
|
|
currentLocation?.let { |
|
|
|
|
Timber.d("Current location: ${it.latitude}, ${it.longitude}") |
|
|
|
|
location.latitude = currentLocation.latitude |
|
|
|
|
location.longitude = currentLocation.longitude |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (success && places.size > 0) { |
|
|
|
|
rowPlaces.clear() |
|
|
|
|
placesForRows.clear() |
|
|
|
|
|
|
|
|
|
for ((index, place) in places.withIndex()) { |
|
|
|
|
if (index < maxResults) { |
|
|
|
|
val row = CustomizableRowRepresentable(customViewType = RowViewType.LOCATION_TITLE, title = place.place.name, isSelectable = true) |
|
|
|
|
rowPlaces.add(row) |
|
|
|
|
placesForRows[row] = place |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
locationActivated = true |
|
|
|
|
isLookingForPlaces = false |
|
|
|
|
updateAdapterUI() |
|
|
|
|
} else { |
|
|
|
|
isLookingForPlaces = false |
|
|
|
|
locationActivated = false |
|
|
|
|
updateAdapterUI() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|