|
|
|
@ -6,12 +6,17 @@ import android.view.View |
|
|
|
import android.view.ViewGroup |
|
|
|
import android.view.ViewGroup |
|
|
|
import androidx.appcompat.widget.AppCompatTextView |
|
|
|
import androidx.appcompat.widget.AppCompatTextView |
|
|
|
import androidx.recyclerview.widget.RecyclerView |
|
|
|
import androidx.recyclerview.widget.RecyclerView |
|
|
|
|
|
|
|
import io.realm.Realm |
|
|
|
|
|
|
|
import io.realm.RealmQuery |
|
|
|
import io.realm.RealmResults |
|
|
|
import io.realm.RealmResults |
|
|
|
|
|
|
|
import io.realm.Sort |
|
|
|
|
|
|
|
import io.realm.kotlin.where |
|
|
|
import kotlinx.android.synthetic.main.row_feed_session.view.* |
|
|
|
import kotlinx.android.synthetic.main.row_feed_session.view.* |
|
|
|
|
|
|
|
import net.pokeranalytics.android.exceptions.PAIllegalStateException |
|
|
|
|
|
|
|
import net.pokeranalytics.android.model.realm.Filter |
|
|
|
import net.pokeranalytics.android.model.realm.Session |
|
|
|
import net.pokeranalytics.android.model.realm.Session |
|
|
|
import net.pokeranalytics.android.ui.view.BindableHolder |
|
|
|
import net.pokeranalytics.android.ui.view.BindableHolder |
|
|
|
import net.pokeranalytics.android.ui.view.RowViewType |
|
|
|
import net.pokeranalytics.android.ui.view.RowViewType |
|
|
|
import net.pokeranalytics.android.util.NULL_TEXT |
|
|
|
|
|
|
|
import net.pokeranalytics.android.util.extensions.getMonthAndYear |
|
|
|
import net.pokeranalytics.android.util.extensions.getMonthAndYear |
|
|
|
import timber.log.Timber |
|
|
|
import timber.log.Timber |
|
|
|
import java.util.* |
|
|
|
import java.util.* |
|
|
|
@ -20,24 +25,70 @@ import kotlin.collections.HashMap |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* An adapter capable of displaying a list of RowRepresentables |
|
|
|
* An adapter capable of displaying a list of RowRepresentables |
|
|
|
* @param dataSource the datasource providing rows |
|
|
|
* The [delegate] is an object notified of UI actions |
|
|
|
* @param delegate the delegate, notified of UI actions |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
class FeedSessionRowRepresentableAdapter( |
|
|
|
class FeedSessionRowRepresentableAdapter( |
|
|
|
var delegate: RowRepresentableDelegate? = null, |
|
|
|
private var realm: Realm, |
|
|
|
var realmResults: RealmResults<Session>, |
|
|
|
var delegate: RowRepresentableDelegate? = null |
|
|
|
var pendingRealmResults: RealmResults<Session>, |
|
|
|
|
|
|
|
var distinctHeaders: RealmResults<Session> |
|
|
|
|
|
|
|
) : |
|
|
|
) : |
|
|
|
RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
|
|
|
RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
|
|
|
|
|
|
|
|
|
|
|
private var headersPositions = HashMap<Int, Date?>() |
|
|
|
private lateinit var startedSessions: RealmResults<Session> |
|
|
|
|
|
|
|
private lateinit var pendingSessions: RealmResults<Session> |
|
|
|
|
|
|
|
|
|
|
|
private lateinit var sortedHeaders: SortedMap<Int, Date?> |
|
|
|
private lateinit var sortedHeaders: SortedMap<Int, Date?> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private var allSessions = mutableListOf<Session>() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var filter: Filter? = null |
|
|
|
|
|
|
|
set(value) { |
|
|
|
|
|
|
|
field = value |
|
|
|
|
|
|
|
filterChanged() |
|
|
|
|
|
|
|
refreshData() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
init { |
|
|
|
init { |
|
|
|
|
|
|
|
defineSessions() // all sessions |
|
|
|
refreshData() |
|
|
|
refreshData() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun defineSessions() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.startedSessions = requestNewQuery().isNotNull("startDate").findAll() |
|
|
|
|
|
|
|
.sort("startDate", Sort.DESCENDING) |
|
|
|
|
|
|
|
this.pendingSessions = requestNewQuery().isNull("startDate").findAll() |
|
|
|
|
|
|
|
.sort("creationDate", Sort.DESCENDING) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Timber.d(">>> startedSessions count = ${startedSessions.size}") |
|
|
|
|
|
|
|
// Timber.d(">>> pendingSessions count = ${pendingSessions.size}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// listeners |
|
|
|
|
|
|
|
this.startedSessions.addChangeListener { _, _ -> |
|
|
|
|
|
|
|
refreshData() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.pendingSessions.addChangeListener { _, _ -> |
|
|
|
|
|
|
|
refreshData() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun requestNewQuery() : RealmQuery<Session> { |
|
|
|
|
|
|
|
this.filter?.let { |
|
|
|
|
|
|
|
return it.query() |
|
|
|
|
|
|
|
} ?: run { |
|
|
|
|
|
|
|
return realm.where() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun filterChanged() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.startedSessions.removeAllChangeListeners() |
|
|
|
|
|
|
|
this.pendingSessions.removeAllChangeListeners() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defineSessions() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Display a session view |
|
|
|
* Display a session view |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@ -88,7 +139,7 @@ class FeedSessionRowRepresentableAdapter( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
override fun getItemCount(): Int { |
|
|
|
override fun getItemCount(): Int { |
|
|
|
return realmResults.size + pendingRealmResults.size + distinctHeaders.size |
|
|
|
return allSessions.size + sortedHeaders.size |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { |
|
|
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { |
|
|
|
@ -110,27 +161,24 @@ class FeedSessionRowRepresentableAdapter( |
|
|
|
context.getString(net.pokeranalytics.android.R.string.pending) |
|
|
|
context.getString(net.pokeranalytics.android.R.string.pending) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// Else, return the formatted date |
|
|
|
// Else, return the formatted date |
|
|
|
val realmHeaderPosition = if (pendingRealmResults.size > 0) sortedHeaders.keys.indexOf(position) - 1 else sortedHeaders.keys.indexOf(position) |
|
|
|
sortedHeaders[position]?.getMonthAndYear() ?: throw PAIllegalStateException("Null date should not happen there") |
|
|
|
distinctHeaders[realmHeaderPosition]?.startDate?.getMonthAndYear() ?: "" |
|
|
|
|
|
|
|
|
|
|
|
// val realmHeaderPosition = sortedHeaders.keys.indexOf(position) |
|
|
|
|
|
|
|
// distinctHeaders[realmHeaderPosition]?.startDate?.getMonthAndYear() ?: throw PAIllegalStateException("Null date should not happen there") |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return NULL_TEXT |
|
|
|
throw PAIllegalStateException("Any position should always have a header, position = $position") |
|
|
|
|
|
|
|
// return NULL_TEXT |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun sessionIdForPosition(position: Int): String? { |
|
|
|
fun sessionIdForPosition(position: Int): String? { |
|
|
|
val session = this.getSessionForPosition(position) |
|
|
|
return this.getSessionForPosition(position)?.id |
|
|
|
return session?.id |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Get real index |
|
|
|
* Get real index |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private fun getSessionForPosition(position: Int): Session? { |
|
|
|
private fun getSessionForPosition(position: Int): Session? { |
|
|
|
return if (pendingRealmResults.size > 0 && position < pendingRealmResults.size + 1) { |
|
|
|
|
|
|
|
// If we have pending session & the position is between these sessions |
|
|
|
|
|
|
|
pendingRealmResults[position - 1] |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// Else, return the correct session |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Row position |
|
|
|
// Row position |
|
|
|
var headersBefore = 0 |
|
|
|
var headersBefore = 0 |
|
|
|
@ -141,9 +189,8 @@ class FeedSessionRowRepresentableAdapter( |
|
|
|
break |
|
|
|
break |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Timber.d("getSessionForPosition = ${position}, headersBefore = $headersBefore") |
|
|
|
realmResults[position - headersBefore - pendingRealmResults.size] |
|
|
|
return allSessions[position - headersBefore] |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -151,12 +198,15 @@ class FeedSessionRowRepresentableAdapter( |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun refreshData() { |
|
|
|
fun refreshData() { |
|
|
|
|
|
|
|
|
|
|
|
headersPositions.clear() |
|
|
|
allSessions.clear() |
|
|
|
|
|
|
|
allSessions.addAll(this.pendingSessions) |
|
|
|
|
|
|
|
allSessions.addAll(this.startedSessions) |
|
|
|
|
|
|
|
|
|
|
|
// If we have pending sessions, set the first header to null |
|
|
|
// allSessions.forEach { |
|
|
|
if (pendingRealmResults.size > 0) { |
|
|
|
// Timber.d(">>> startdate = ${it.startDate}, creationDate = ${it.creationDate}") |
|
|
|
headersPositions[0] = null |
|
|
|
// } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val headersPositions = HashMap<Int, Date?>() |
|
|
|
|
|
|
|
|
|
|
|
val start = System.currentTimeMillis() |
|
|
|
val start = System.currentTimeMillis() |
|
|
|
|
|
|
|
|
|
|
|
@ -166,14 +216,22 @@ class FeedSessionRowRepresentableAdapter( |
|
|
|
val calendar = Calendar.getInstance() |
|
|
|
val calendar = Calendar.getInstance() |
|
|
|
|
|
|
|
|
|
|
|
// Add headers if the date doesn't exist yet |
|
|
|
// Add headers if the date doesn't exist yet |
|
|
|
for ((index, session) in realmResults.withIndex()) { |
|
|
|
for ((index, session) in allSessions.withIndex()) { |
|
|
|
calendar.time = session.startDate ?: session.creationDate |
|
|
|
// Timber.d("/// $index > date = ${session.startDate}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val startDate = session.startDate |
|
|
|
|
|
|
|
if (startDate == null) { |
|
|
|
|
|
|
|
headersPositions[0] = null |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
calendar.time = startDate |
|
|
|
if (checkHeaderCondition(calendar, previousYear, previousMonth)) { |
|
|
|
if (checkHeaderCondition(calendar, previousYear, previousMonth)) { |
|
|
|
headersPositions[index + headersPositions.size + pendingRealmResults.size] = session.startDate ?: session.creationDate |
|
|
|
// Timber.d("ADDS HEADER for position= ${index + headersPositions.size}, date = ${session.startDate}") |
|
|
|
|
|
|
|
headersPositions[index + headersPositions.size] = startDate |
|
|
|
previousYear = calendar.get(Calendar.YEAR) |
|
|
|
previousYear = calendar.get(Calendar.YEAR) |
|
|
|
previousMonth = calendar.get(Calendar.MONTH) |
|
|
|
previousMonth = calendar.get(Calendar.MONTH) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sortedHeaders = headersPositions.toSortedMap() |
|
|
|
sortedHeaders = headersPositions.toSortedMap() |
|
|
|
|
|
|
|
|
|
|
|
@ -183,7 +241,7 @@ class FeedSessionRowRepresentableAdapter( |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Check if we need to add a header |
|
|
|
* Check if we need to add a header |
|
|
|
* Can be change to manage different condition |
|
|
|
* Can be changed to manage different condition |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private fun checkHeaderCondition(currentCalendar: Calendar, previousYear: Int, previousMonth: Int) : Boolean { |
|
|
|
private fun checkHeaderCondition(currentCalendar: Calendar, previousYear: Int, previousMonth: Int) : Boolean { |
|
|
|
return currentCalendar.get(Calendar.YEAR) == previousYear && currentCalendar.get(Calendar.MONTH) < previousMonth || (currentCalendar.get(Calendar.YEAR) < previousYear) |
|
|
|
return currentCalendar.get(Calendar.YEAR) == previousYear && currentCalendar.get(Calendar.MONTH) < previousMonth || (currentCalendar.get(Calendar.YEAR) < previousYear) |
|
|
|
|