diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/HistoryRowRepresentableAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/HistorySessionRowRepresentableAdapter.kt similarity index 56% rename from app/src/main/java/net/pokeranalytics/android/ui/adapter/HistoryRowRepresentableAdapter.kt rename to app/src/main/java/net/pokeranalytics/android/ui/adapter/HistorySessionRowRepresentableAdapter.kt index 60a872c4..d80db269 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/HistoryRowRepresentableAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/HistorySessionRowRepresentableAdapter.kt @@ -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, +class HistorySessionRowRepresentableAdapter( var delegate: RowRepresentableDelegate? = null, - var headers: RealmResults + var realmResults: RealmResults, + var pendingRealmResults: RealmResults, + var distinctHeaders: RealmResults ) : RecyclerView.Adapter() { - private var headersPositions = HashMap() - private lateinit var sortedHeaders: SortedMap + private var headersPositions = HashMap() + private lateinit var sortedHeaders: SortedMap 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(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) + + } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt index bd61a032..d0775ba2 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt @@ -12,7 +12,7 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.model.interfaces.Manageable import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.ui.activity.SessionActivity -import net.pokeranalytics.android.ui.adapter.HistoryRowRepresentableAdapter +import net.pokeranalytics.android.ui.adapter.HistorySessionRowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.LiveRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment @@ -31,9 +31,9 @@ class HistoryFragment : PokerAnalyticsFragment(), LiveRowRepresentableDataSource } } - private lateinit var historyAdapter: HistoryRowRepresentableAdapter + private lateinit var historyAdapter: HistorySessionRowRepresentableAdapter // Old - //private lateinit var historyAdapter: HistoryRowRepresentableAdapter + //private lateinit var historyAdapter: HistorySessionRowRepresentableAdapter private lateinit var realmSessions: RealmResults private val sessions: ArrayList = ArrayList() private val rows: ArrayList = ArrayList() @@ -81,22 +81,22 @@ class HistoryFragment : PokerAnalyticsFragment(), LiveRowRepresentableDataSource * Init data */ private fun initData() { - realmSessions = getRealm().where().findAll().sort("creationDate", Sort.DESCENDING) - - val viewManager = SmoothScrollLinearLayoutManager(requireContext()) + realmSessions = getRealm().where().findAll().sort("startDate", Sort.DESCENDING) realmSessions.addChangeListener { t, changeSet -> if (changeSet.insertions.isNotEmpty() || changeSet.deletions.isNotEmpty()) { historyAdapter.refreshData() } historyAdapter.notifyDataSetChanged() } - val months = getRealm().where().distinct("year", "month").findAll().sort("creationDate", Sort.DESCENDING) - historyAdapter = HistoryRowRepresentableAdapter(realmSessions, this, months) - // Old - //historyAdapter = RowRepresentableAdapter(this, this) + val startedSessions = getRealm().where().isNotNull("year").isNotNull("month").findAll().sort("startDate", Sort.DESCENDING) + val pendingSessions = getRealm().where().isNull("year").isNull("month").findAll().sort("startDate", Sort.DESCENDING) + val distinctDateSessions = getRealm().where().distinct("year", "month").findAll().sort("startDate", Sort.DESCENDING) + + historyAdapter = HistorySessionRowRepresentableAdapter(this, startedSessions, pendingSessions, distinctDateSessions) + val viewManager = SmoothScrollLinearLayoutManager(requireContext()) recyclerView.apply { setHasFixedSize(true) layoutManager = viewManager @@ -104,66 +104,6 @@ class HistoryFragment : PokerAnalyticsFragment(), LiveRowRepresentableDataSource } } - /** - * Create the endedSessions headers - * TODO: Remove - */ - private fun createSessionsHeaders() { - - /* - val start = System.currentTimeMillis() - - val oldRows = ArrayList() - oldRows.addAll(rows) - - rows.clear() - sessions.clear() - sessions.addAll(getRealm().copyFromRealm(realmSessions)) - noSessionFound.isVisible = sessions.isEmpty() - - GlobalScope.launch { - - val groupedByDay = false - val calendar = Calendar.getInstance() - val currentCalendar = Calendar.getInstance() - - for ((index, session) in sessions.withIndex()) { - currentCalendar.time = session.creationDate - if (groupedByDay) { - if (!calendar.isSameDay(currentCalendar) || index == 0) { - calendar.time = currentCalendar.time - val header = CustomizableRowRepresentable( - customViewType = RowViewType.HEADER_TITLE, - title = session.creationDate.longDate() - ) - rows.add(header) - } - } else { - if (!calendar.isSameMonth(currentCalendar) || index == 0) { - calendar.time = currentCalendar.time - val header = CustomizableRowRepresentable( - customViewType = RowViewType.HEADER_TITLE, - title = session.creationDate.getMonthAndYear() - ) - rows.add(header) - } - } - rows.add(session) - } - - val diffResult = DiffUtil.calculateDiff(HistorySessionDiffCallback(rows, oldRows)) - historyAdapter.updateRows(diffResult) - - if (newSessionCreated) { - newSessionCreated = false - recyclerView.smoothScrollToPosition(0) - } - - Timber.d("createSessionsHeaders in: ${System.currentTimeMillis() - start}ms") - } - */ - } - override fun rowRepresentableForPosition(position: Int): RowRepresentable? { return this.rows[position] } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4033df14..1671c816 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,6 +31,8 @@ Tournament Feature New + Pending + %s ago