|
|
|
|
@ -1,5 +1,6 @@ |
|
|
|
|
package net.pokeranalytics.android.ui.adapter |
|
|
|
|
|
|
|
|
|
import android.content.Context |
|
|
|
|
import android.view.LayoutInflater |
|
|
|
|
import android.view.View |
|
|
|
|
import android.view.ViewGroup |
|
|
|
|
@ -11,6 +12,7 @@ import net.pokeranalytics.android.R |
|
|
|
|
import net.pokeranalytics.android.model.realm.Session |
|
|
|
|
import net.pokeranalytics.android.ui.view.BindableHolder |
|
|
|
|
import net.pokeranalytics.android.ui.view.RowViewType |
|
|
|
|
import net.pokeranalytics.android.util.NULL_TEXT |
|
|
|
|
import net.pokeranalytics.android.util.extensions.getMonthAndYear |
|
|
|
|
import timber.log.Timber |
|
|
|
|
import java.util.* |
|
|
|
|
@ -22,15 +24,16 @@ import kotlin.collections.HashMap |
|
|
|
|
* @param dataSource the datasource providing rows |
|
|
|
|
* @param delegate the delegate, notified of UI actions |
|
|
|
|
*/ |
|
|
|
|
class HistoryRowRepresentableAdapter( |
|
|
|
|
var realmResults: RealmResults<Session>, |
|
|
|
|
class HistorySessionRowRepresentableAdapter( |
|
|
|
|
var delegate: RowRepresentableDelegate? = null, |
|
|
|
|
var headers: RealmResults<Session> |
|
|
|
|
var realmResults: RealmResults<Session>, |
|
|
|
|
var pendingRealmResults: RealmResults<Session>, |
|
|
|
|
var distinctHeaders: RealmResults<Session> |
|
|
|
|
) : |
|
|
|
|
RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
|
|
|
|
|
|
|
|
|
private var headersPositions = HashMap<Int, Date>() |
|
|
|
|
private lateinit var sortedHeaders: SortedMap<Int, Date> |
|
|
|
|
private var headersPositions = HashMap<Int, Date?>() |
|
|
|
|
private lateinit var sortedHeaders: SortedMap<Int, Date?> |
|
|
|
|
|
|
|
|
|
init { |
|
|
|
|
refreshData() |
|
|
|
|
@ -40,7 +43,7 @@ class HistoryRowRepresentableAdapter( |
|
|
|
|
* Display a session view |
|
|
|
|
*/ |
|
|
|
|
inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { |
|
|
|
|
fun bind(position: Int, row: Session?, adapter: HistoryRowRepresentableAdapter) { |
|
|
|
|
fun bind(position: Int, row: Session?, adapter: HistorySessionRowRepresentableAdapter) { |
|
|
|
|
|
|
|
|
|
itemView.sessionRow.setData(row as Session) |
|
|
|
|
val listener = View.OnClickListener { |
|
|
|
|
@ -54,10 +57,10 @@ class HistoryRowRepresentableAdapter( |
|
|
|
|
* Display a session view |
|
|
|
|
*/ |
|
|
|
|
inner class HeaderTitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { |
|
|
|
|
fun bind(position: Int, session: Session?, adapter: HistoryRowRepresentableAdapter) { |
|
|
|
|
fun bind(position: Int, title: String, adapter: HistorySessionRowRepresentableAdapter) { |
|
|
|
|
// Title |
|
|
|
|
itemView.findViewById<AppCompatTextView>(R.id.title)?.let { |
|
|
|
|
it.text = session?.creationDate?.getMonthAndYear() |
|
|
|
|
it.text = title |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -83,27 +86,45 @@ class HistoryRowRepresentableAdapter( |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun getItemCount(): Int { |
|
|
|
|
return realmResults.size + headers.size |
|
|
|
|
return realmResults.size + pendingRealmResults.size + distinctHeaders.size |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { |
|
|
|
|
if (holder is RowSessionViewHolder) { |
|
|
|
|
holder.bind(position, realmResults[getRealIndex(position)], this) |
|
|
|
|
holder.bind(position, getSessionForPosition(position), this) |
|
|
|
|
} else if (holder is HeaderTitleViewHolder) { |
|
|
|
|
holder.bind(position, headers[getRealIndex(position)], this) |
|
|
|
|
holder.bind(position, getHeaderForPosition(holder.itemView.context, position), this) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Get real index |
|
|
|
|
* Return the header |
|
|
|
|
*/ |
|
|
|
|
private fun getRealIndex(position: Int): Int { |
|
|
|
|
|
|
|
|
|
private fun getHeaderForPosition(context: Context, position :Int) : String { |
|
|
|
|
if (sortedHeaders.containsKey(position)) { |
|
|
|
|
// Header position |
|
|
|
|
//Timber.d("getRealIndex: Header: ${sortedHeaders.keys.indexOf(position)}") |
|
|
|
|
return sortedHeaders.keys.indexOf(position) |
|
|
|
|
|
|
|
|
|
// If the header has no date, it's a pending session |
|
|
|
|
return if (sortedHeaders[position] == null) { |
|
|
|
|
context.getString(R.string.pending) |
|
|
|
|
} else { |
|
|
|
|
// Else, return the formatted date |
|
|
|
|
val realmHeaderPosition = if (pendingRealmResults.size > 0) sortedHeaders.keys.indexOf(position) - 1 else sortedHeaders.keys.indexOf(position) |
|
|
|
|
distinctHeaders[realmHeaderPosition]?.startDate?.getMonthAndYear() ?: "" |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return NULL_TEXT |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Get real index |
|
|
|
|
*/ |
|
|
|
|
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 |
|
|
|
|
var headersBefore = 0 |
|
|
|
|
for (key in sortedHeaders.keys) { |
|
|
|
|
@ -113,8 +134,8 @@ class HistoryRowRepresentableAdapter( |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
//Timber.d("getRealIndex: Row: $position $headersBefore") |
|
|
|
|
return position - headersBefore |
|
|
|
|
|
|
|
|
|
realmResults[position - headersBefore - pendingRealmResults.size] |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -124,17 +145,24 @@ class HistoryRowRepresentableAdapter( |
|
|
|
|
fun refreshData() { |
|
|
|
|
|
|
|
|
|
headersPositions.clear() |
|
|
|
|
|
|
|
|
|
// If we have pending sessions, set the first header to null |
|
|
|
|
if (pendingRealmResults.size > 0) { |
|
|
|
|
headersPositions[0] = null |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val start = System.currentTimeMillis() |
|
|
|
|
|
|
|
|
|
var previousYear = 0 |
|
|
|
|
var previousMonth = 0 |
|
|
|
|
var previousYear = Int.MAX_VALUE |
|
|
|
|
var previousMonth = Int.MAX_VALUE |
|
|
|
|
|
|
|
|
|
val calendar = Calendar.getInstance() |
|
|
|
|
|
|
|
|
|
// Add headers if the date doesn't exist yet |
|
|
|
|
for ((index, session) in realmResults.withIndex()) { |
|
|
|
|
calendar.time = session.creationDate |
|
|
|
|
if (calendar.get(Calendar.YEAR) == previousYear && calendar.get(Calendar.MONTH) < previousMonth || (calendar.get(Calendar.YEAR) < previousYear) || index == 0) { |
|
|
|
|
headersPositions[index + headersPositions.size] = session.creationDate |
|
|
|
|
if (checkHeaderCondition(calendar, previousYear, previousMonth)) { |
|
|
|
|
headersPositions[index + headersPositions.size + pendingRealmResults.size] = session.creationDate |
|
|
|
|
previousYear = calendar.get(Calendar.YEAR) |
|
|
|
|
previousMonth = calendar.get(Calendar.MONTH) |
|
|
|
|
} |
|
|
|
|
@ -145,5 +173,14 @@ class HistoryRowRepresentableAdapter( |
|
|
|
|
Timber.d("Create viewTypesPositions in: ${System.currentTimeMillis() - start}ms") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Check if we need to add a header |
|
|
|
|
* Can be change to manage different condition |
|
|
|
|
*/ |
|
|
|
|
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) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |