merge conflicts fix

feature/top10
Razmig Sarkissian 7 years ago
commit 40ac353039
  1. 4
      app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt
  2. 58
      app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt
  3. 37
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  4. 29
      app/src/main/java/net/pokeranalytics/android/ui/activity/components/PokerAnalyticsActivity.kt
  5. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/CurrenciesFragment.kt
  6. 28
      app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt
  7. 6
      app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt
  8. 207
      app/src/main/java/net/pokeranalytics/android/ui/fragment/LocationDataFragment.kt
  9. 1
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt
  10. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatsFragment.kt
  11. 14
      app/src/main/java/net/pokeranalytics/android/ui/view/HistorySessionDiffCallback.kt
  12. 26
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  13. 9
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/CustomizableRowRepresentable.kt
  14. 16
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/LocationRow.kt
  15. 10
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt
  16. 26
      app/src/main/java/net/pokeranalytics/android/util/LocationManager.kt
  17. 37
      app/src/main/res/layout/row_loader.xml
  18. 1
      app/src/main/res/values/strings.xml

@ -7,7 +7,3 @@ class ModelException(message: String) : Exception(message) {
class FormattingException(message: String) : Exception(message) {
}
class TypeException(message: String) : Exception(message) {
}

@ -2,20 +2,15 @@ package net.pokeranalytics.android.model.realm
import com.google.android.libraries.places.api.model.Place
import io.realm.RealmObject
import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.Manageable
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.rowrepresentable.LocationRow
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow
import java.util.*
import kotlin.collections.ArrayList
open class Location : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable {
open class Location : RealmObject(), Manageable, RowRepresentable {
@PrimaryKey
var id = UUID.randomUUID().toString()
@ -32,9 +27,6 @@ open class Location : RealmObject(), Manageable, StaticRowRepresentableDataSourc
// the latitude of the location
var latitude: Double? = null
@Ignore
var isLookingForPlaces = false
override fun getDisplayName(): String {
return this.name
}
@ -43,58 +35,10 @@ open class Location : RealmObject(), Manageable, StaticRowRepresentableDataSourc
return this.id
}
override fun adapterRows(): List<RowRepresentable>? {
val rows = ArrayList<RowRepresentable>()
rows.add(SimpleRow.NAME)
rows.addAll(LocationRow.values())
return rows
}
override fun stringForRow(row: RowRepresentable): String {
return when (row) {
SimpleRow.NAME -> this.name
LocationRow.ADDRESS -> this.address
else -> return super.stringForRow(row)
}
}
override fun boolForRow(row: RowRepresentable): Boolean {
return when(row) {
LocationRow.LOCATE_ME -> return isLookingForPlaces
else -> super.boolForRow(row)
}
}
override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor> {
val data = java.util.ArrayList<RowRepresentableEditDescriptor>()
when (row) {
SimpleRow.NAME -> data.add(
RowRepresentableEditDescriptor(
this.name,
SimpleRow.NAME.resId
)
)
LocationRow.ADDRESS -> data.add(
RowRepresentableEditDescriptor(
this.address,
LocationRow.ADDRESS.resId
)
)
}
return data
}
override fun updateValue(value: Any?, row: RowRepresentable) {
when (row) {
SimpleRow.NAME -> this.name = value as String? ?: ""
LocationRow.ADDRESS -> this.address = value as String? ?: ""
LocationRow.LOCATE_ME -> {
isLookingForPlaces = false
if (value is Place) {
setPlace(value)
}
}
}
}

@ -28,11 +28,10 @@ import net.pokeranalytics.android.ui.adapter.UnmanagedRowRepresentableException
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.HeaderRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import net.pokeranalytics.android.util.*
import timber.log.Timber
import java.util.*
import java.util.Currency
import kotlin.collections.ArrayList
@ -480,14 +479,14 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
@Ignore
private var rowRepresentationForCurrentState : List<RowRepresentable> = this.updatedRowRepresentationForCurrentState()
fun updatedRowRepresentationForCurrentState(): List<RowRepresentable> {
private fun updatedRowRepresentationForCurrentState(): List<RowRepresentable> {
val rows = ArrayList<RowRepresentable>()
// Headers
when (getState()) {
SessionState.STARTED -> {
rows.add(
HeaderRowRepresentable(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG,
title = getFormattedDuration(),
computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0)
@ -497,7 +496,7 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
}
SessionState.PAUSED -> {
rows.add(
HeaderRowRepresentable(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG,
resId = R.string.pause,
computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0)
@ -507,33 +506,29 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
}
SessionState.FINISHED -> {
rows.add(
HeaderRowRepresentable(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT_BIG,
title = getFormattedDuration(),
computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0)
)
)
rows.add(
HeaderRowRepresentable(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_AMOUNT,
resId = R.string.hour_rate_without_pauses,
computedStat = ComputedStat(Stat.HOURLY_RATE, this.hourlyRate)
)
)
//TODO V2: Add Bankroll variation
/*
if (!isTournament()) {
rows.add(
HeaderRowRepresentable(
RowViewType.HEADER_TITLE_VALUE,
resId = R.string.bankroll_variation,
computedStat = ComputedStat(Stat.HOURLY_RATE, 0.0)
)
)
}
*/
if (!isTournament()) {
rows.add(
CustomizableRowRepresentable(
RowViewType.HEADER_TITLE_VALUE,
resId = R.string.bankroll_variation,
computedStat = ComputedStat(Stat.HOURLY_RATE, 0.0)
)
)
}
rows.add(SeparatorRowRepresentable())
}
else -> {
@ -545,7 +540,7 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
return rows
}
fun updateRowRepresentation() {
private fun updateRowRepresentation() {
this.rowRepresentationForCurrentState = this.updatedRowRepresentationForCurrentState()
}

@ -68,6 +68,13 @@ open class PokerAnalyticsActivity : AppCompatActivity() {
return realm
}
/**
* Return if the location permission has been granted by the user
*/
fun hasLocationPermissionGranted() : Boolean {
return ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
/**
* Ask for location permission
*/
@ -78,7 +85,6 @@ open class PokerAnalyticsActivity : AppCompatActivity() {
)
}
/**
* Ask for places request
*/
@ -118,4 +124,25 @@ open class PokerAnalyticsActivity : AppCompatActivity() {
}
}
/**
* Find the current location
*/
fun findCurrentLocation(callback: ((location: Location?) -> Unit)?) {
if (LocationManager(this).databaseContainsLocationsWithCoordinates()) {
if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationManager(this).findNearestLocationFromUser(callback)
} else {
askForLocationPermission { granted ->
if (granted) {
LocationManager(this).findNearestLocationFromUser(callback)
} else {
callback?.invoke(null)
}
}
}
} else {
callback?.invoke(null)
}
}
}

@ -1,7 +1,6 @@
package net.pokeranalytics.android.ui.fragment
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -16,7 +15,6 @@ import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.HeaderRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRowRepresentable
import net.pokeranalytics.android.util.Preferences
import java.util.*

@ -4,7 +4,6 @@ import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Bundle
import android.view.*
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.RealmObject
@ -35,7 +34,9 @@ open class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDele
private var editableMenu: Menu? = null
private var dataType: Int? = null
private var primaryKey: String? = null
private var isUpdating = false
var isUpdating = false
var shouldOpenKeyboard = true
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_editable_data, container, false)
@ -64,7 +65,7 @@ open class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDele
}
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
BottomSheetFragment.create(fragmentManager, row, this, (this.item as RowRepresentableDataSource).editDescriptors(row))
BottomSheetFragment.create(fragmentManager, row, this, getDataSource().editDescriptors(row))
}
override fun onRowValueChanged(value: Any?, row: RowRepresentable) {
@ -91,6 +92,12 @@ open class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDele
}
}
/**
* Return the data source
*/
open fun getDataSource(): RowRepresentableDataSource {
return this.item as RowRepresentableDataSource
}
/**
* Init data
@ -99,21 +106,22 @@ open class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDele
if (this.dataType != null) {
val proxyItem: RealmObject? = this.liveDataType.getData(this.getRealm(), primaryKey)
proxyItem?.let {
//TODO: Localize
this.appBar.toolbar.title = "Update ${this.liveDataType.localizedTitle(this.parentActivity).toLowerCase().capitalize()}"
isUpdating = true
} ?: run {
//TODO: Localize
this.appBar.toolbar.title = "New ${this.liveDataType.localizedTitle(this.parentActivity).toLowerCase().capitalize()}"
}
this.item = this.liveDataType.updateOrCreate(this.getRealm(), primaryKey)
this.rowRepresentableAdapter = RowRepresentableAdapter(
(this.item as RowRepresentableDataSource),
this
)
val dataSource = getDataSource()
this.rowRepresentableAdapter = RowRepresentableAdapter(getDataSource(), this)
this.recyclerView.adapter = rowRepresentableAdapter
// When creating an object, open automatically the keyboard for the first row
if (!isUpdating && this.item is RowRepresentableDataSource) {
val row = (this.item as RowRepresentableDataSource).adapterRows()?.firstOrNull()
if (!isUpdating && shouldOpenKeyboard) {
val row = dataSource.adapterRows()?.firstOrNull()
row?.let {
onRowSelected(0, it)
}
@ -132,7 +140,7 @@ open class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDele
/**
* Save data
*/
private fun saveData() {
fun saveData() {
if ((this.item as Savable).isValidForSave()) {
this.getRealm().executeTransaction {
val item = it.copyToRealmOrUpdate(this.item)

@ -24,7 +24,7 @@ import net.pokeranalytics.android.ui.view.HistorySessionDiffCallback
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager
import net.pokeranalytics.android.ui.view.rowrepresentable.HeaderRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.util.getMonthAndYear
import net.pokeranalytics.android.util.isSameDay
import net.pokeranalytics.android.util.isSameMonth
@ -128,7 +128,7 @@ class HistoryFragment : PokerAnalyticsFragment(), LiveRowRepresentableDataSource
if (groupedByDay) {
if (!calendar.isSameDay(currentCalendar) || index == 0) {
calendar.time = currentCalendar.time
val header = HeaderRowRepresentable(
val header = CustomizableRowRepresentable(
customViewType = RowViewType.HEADER_TITLE,
title = session.creationDate.longDate()
)
@ -137,7 +137,7 @@ class HistoryFragment : PokerAnalyticsFragment(), LiveRowRepresentableDataSource
} else {
if (!calendar.isSameMonth(currentCalendar) || index == 0) {
calendar.time = currentCalendar.time
val header = HeaderRowRepresentable(
val header = CustomizableRowRepresentable(
customViewType = RowViewType.HEADER_TITLE,
title = session.creationDate.getMonthAndYear()
)

@ -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()
}
}
}

@ -224,7 +224,6 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate {
if (scrollToTop) {
recyclerView.smoothScrollToPosition(0)
}
}
}

@ -16,7 +16,7 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.SessionObserverFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.HeaderRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.util.NULL_TEXT
class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSource {
@ -145,7 +145,7 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
val rows: ArrayList<RowRepresentable> = ArrayList()
results.forEach { results ->
rows.add(HeaderRowRepresentable(title = results.group.name))
rows.add(CustomizableRowRepresentable(title = results.group.name))
results.group.stats?.forEach { stat ->
rows.add(StatRepresentable(stat, results.computedStat(stat)))
}

@ -3,7 +3,7 @@ package net.pokeranalytics.android.ui.view
import androidx.annotation.Nullable
import androidx.recyclerview.widget.DiffUtil
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.view.rowrepresentable.HeaderRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
class HistorySessionDiffCallback(var newRows: List<RowRepresentable>, var oldRows: List<RowRepresentable>) :
DiffUtil.Callback() {
@ -22,9 +22,9 @@ class HistorySessionDiffCallback(var newRows: List<RowRepresentable>, var oldRow
val session1 = oldRows[oldItemPosition] as Session
val session2 = newRows[newItemPosition] as Session
return session1.id == session2.id
} else if (oldRows[oldItemPosition] is HeaderRowRepresentable && newRows[newItemPosition] is HeaderRowRepresentable) {
val header1 = oldRows[oldItemPosition] as HeaderRowRepresentable
val header2 = newRows[newItemPosition] as HeaderRowRepresentable
} else if (oldRows[oldItemPosition] is CustomizableRowRepresentable && newRows[newItemPosition] is CustomizableRowRepresentable) {
val header1 = oldRows[oldItemPosition] as CustomizableRowRepresentable
val header2 = newRows[newItemPosition] as CustomizableRowRepresentable
return header1.title == header2.title
}
@ -40,9 +40,9 @@ class HistorySessionDiffCallback(var newRows: List<RowRepresentable>, var oldRow
return false //session1.id == session2.id
} else if (oldRows[oldItemPosition] is HeaderRowRepresentable && newRows[newItemPosition] is HeaderRowRepresentable) {
val header1 = oldRows[oldItemPosition] as HeaderRowRepresentable
val header2 = newRows[newItemPosition] as HeaderRowRepresentable
} else if (oldRows[oldItemPosition] is CustomizableRowRepresentable && newRows[newItemPosition] is CustomizableRowRepresentable) {
val header1 = oldRows[oldItemPosition] as CustomizableRowRepresentable
val header2 = newRows[newItemPosition] as CustomizableRowRepresentable
return header1.title == header2.title
}

@ -14,7 +14,7 @@ import kotlinx.android.synthetic.main.row_history_session.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.view.rowrepresentable.HeaderRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
/**
* An interface used to factor the configuration of RecyclerView.ViewHolder
@ -35,6 +35,7 @@ enum class RowViewType(private var layoutRes: Int) {
HEADER_TITLE_VALUE(R.layout.row_header_title_value),
HEADER_TITLE_AMOUNT(R.layout.row_header_title_amount),
HEADER_TITLE_AMOUNT_BIG(R.layout.row_header_title_amount_big),
LOCATION_TITLE(R.layout.row_title),
// Row
TITLE(R.layout.row_title),
@ -46,6 +47,7 @@ enum class RowViewType(private var layoutRes: Int) {
DATA(R.layout.row_title),
BOTTOM_SHEET_DATA(R.layout.row_bottom_sheet_title),
TITLE_CHECK(R.layout.row_title_check),
LOADER(R.layout.row_loader),
// Custom row
ROW_SESSION(R.layout.row_history_session),
@ -66,10 +68,10 @@ enum class RowViewType(private var layoutRes: Int) {
return when (this) {
// Header Row View Holder
HEADER_TITLE, HEADER_TITLE_VALUE, HEADER_TITLE_AMOUNT, HEADER_TITLE_AMOUNT_BIG -> HeaderViewHolder(layout)
HEADER_TITLE, HEADER_TITLE_VALUE, HEADER_TITLE_AMOUNT, HEADER_TITLE_AMOUNT_BIG, LOCATION_TITLE -> TitleViewHolder(layout)
// Row View Holder
TITLE, TITLE_ARROW, TITLE_VALUE, TITLE_VALUE_ARROW, TITLE_GRID, TITLE_SWITCH, TITLE_CHECK, DATA, BOTTOM_SHEET_DATA -> RowViewHolder(
TITLE, TITLE_ARROW, TITLE_VALUE, TITLE_VALUE_ARROW, TITLE_GRID, TITLE_SWITCH, TITLE_CHECK, DATA, BOTTOM_SHEET_DATA, LOADER -> RowViewHolder(
layout
)
@ -96,10 +98,10 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a header
*/
inner class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class TitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
if (row is HeaderRowRepresentable) {
if (row is CustomizableRowRepresentable) {
// Title
itemView.findViewById<AppCompatTextView>(R.id.title)?.let {
@ -116,6 +118,18 @@ enum class RowViewType(private var layoutRes: Int) {
it.text = row.value
}
}
// Listener
row.isSelectable?.let { isSelectable ->
if (isSelectable) {
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.findViewById<View?>(R.id.container)?.let {
it.setOnClickListener(listener)
}
}
}
}
}
}
@ -199,7 +213,7 @@ enum class RowViewType(private var layoutRes: Int) {
itemView.findViewById<AppCompatTextView?>(R.id.title)?.text = row.localizedTitle(itemView.context)
// Value
itemView.findViewById<AppCompatTextView?>(R.id.value)?.let {view ->
itemView.findViewById<AppCompatTextView?>(R.id.value)?.let { view ->
adapter.dataSource.contentDescriptorForRow(row)?.textFormat?.let {
view.text = it.text
view.setTextColor(it.getColor(itemView.context))

@ -6,14 +6,15 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
/**
* A class to display headers as row representable
* A class to display a title (and a value) as a Row Representable object
*/
class HeaderRowRepresentable(
class CustomizableRowRepresentable(
var customViewType: RowViewType? = RowViewType.HEADER_TITLE,
override var resId: Int? = null,
var title: String? = null,
var value: String? = null,
var computedStat: ComputedStat? = null
var computedStat: ComputedStat? = null,
var isSelectable: Boolean? = false
) : RowRepresentable {
override fun localizedTitle(context: Context): String {
@ -27,8 +28,6 @@ class HeaderRowRepresentable(
return "LOCALISATION NOT FOUND"
}
override val viewType: Int = customViewType?.ordinal ?: RowViewType.HEADER_TITLE.ordinal
}

@ -7,30 +7,30 @@ import net.pokeranalytics.android.ui.view.RowViewType
enum class LocationRow : RowRepresentable {
ADDRESS,
LOCATE_ME;
LOCATION_PERMISSION_SWITCH,
LOCATION_LOADER;
override val resId: Int?
get() {
return when (this) {
ADDRESS -> R.string.address
LOCATE_ME -> R.string.geo_locate
LOCATION_PERMISSION_SWITCH -> R.string.geo_locate
LOCATION_LOADER -> null
}
}
override val viewType: Int
get() {
return when (this) {
ADDRESS -> RowViewType.TITLE_VALUE.ordinal
LOCATE_ME -> RowViewType.ROW_BUTTON.ordinal
LOCATION_PERMISSION_SWITCH -> RowViewType.TITLE_SWITCH.ordinal
LOCATION_LOADER -> RowViewType.LOADER.ordinal
}
}
override val bottomSheetType: BottomSheetType
get() {
return when (this) {
ADDRESS -> BottomSheetType.EDIT_TEXT
LOCATE_ME -> BottomSheetType.NONE
LOCATION_PERMISSION_SWITCH -> BottomSheetType.NONE
LOCATION_LOADER -> BottomSheetType.NONE
}
}

@ -40,24 +40,24 @@ enum class SettingRow : RowRepresentable {
fun getRows(): ArrayList<RowRepresentable> {
val rows = ArrayList<RowRepresentable>()
rows.add(HeaderRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.information))
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.information))
rows.addAll(arrayListOf(VERSION, RATE_APP, CONTACT_US, BUG_REPORT))
rows.add(HeaderRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.follow_us))
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.follow_us))
rows.addAll(arrayListOf(FOLLOW_US))
rows.add(HeaderRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.preferences))
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.preferences))
rows.addAll(arrayListOf(CURRENCY))
rows.add(
HeaderRowRepresentable(
CustomizableRowRepresentable(
customViewType = RowViewType.HEADER_TITLE,
resId = R.string.data_management
)
)
rows.addAll(arrayListOf(BANKROLL, GAME, LOCATION, TOURNAMENT_NAME, TOURNAMENT_FEATURE))
rows.add(HeaderRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.terms))
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.terms))
rows.addAll(arrayListOf(PRIVACY_POLICY, TERMS_OF_USE, GDPR))
return rows

@ -44,6 +44,8 @@ class LocationManager(private var context: Context) {
// Call findCurrentPlace and handle the response (first check that the user has granted permission).
if (ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
val placeResponse = placesClient.findCurrentPlace(request)
placeResponse.addOnCompleteListener { task ->
val places = ArrayList<PlaceLikelihood>()
if (task.isSuccessful) {
@ -142,7 +144,31 @@ class LocationManager(private var context: Context) {
// If we don't have the permission, return null
callback?.invoke(null)
}
}
/**
* Return the current location of the user
*/
fun findCurrentLocation(callback: ((location: android.location.Location?) -> Unit)?) {
val fusedLocationClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context)
if (ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationClient.lastLocation.addOnSuccessListener { location: android.location.Location? ->
// Got last known location. In some rare situations this can be null.
location?.let { currentLocation ->
callback?.invoke(currentLocation)
} ?: run {
// If the current location is null, return null
callback?.invoke(null)
}
}.addOnCanceledListener {
// If there was a problem during the call to last location, return null
callback?.invoke(null)
}
} else {
callback?.invoke(null)
}
}
}

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?selectableItemBackground">
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="0dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineEnd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="0dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -19,6 +19,7 @@
<string name="hands_played">Hands played</string>
<string name="address">Address</string>
<string name="suggestions">Suggestions</string>
<string name="data_deleted" formatted="false">%s deleted</string>
<string name="end_date_not_possible">The end date should be after the start date</string>

Loading…
Cancel
Save