|
|
|
@ -11,14 +11,11 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator |
|
|
|
import androidx.lifecycle.ViewModelProvider |
|
|
|
import androidx.lifecycle.ViewModelProvider |
|
|
|
import androidx.recyclerview.widget.DiffUtil |
|
|
|
import androidx.recyclerview.widget.DiffUtil |
|
|
|
import com.crashlytics.android.Crashlytics |
|
|
|
import com.crashlytics.android.Crashlytics |
|
|
|
import io.realm.annotations.Ignore |
|
|
|
|
|
|
|
import kotlinx.android.synthetic.main.fragment_session.* |
|
|
|
import kotlinx.android.synthetic.main.fragment_session.* |
|
|
|
import kotlinx.coroutines.GlobalScope |
|
|
|
import kotlinx.coroutines.GlobalScope |
|
|
|
import kotlinx.coroutines.async |
|
|
|
import kotlinx.coroutines.async |
|
|
|
import kotlinx.coroutines.launch |
|
|
|
import kotlinx.coroutines.launch |
|
|
|
import net.pokeranalytics.android.R |
|
|
|
import net.pokeranalytics.android.R |
|
|
|
import net.pokeranalytics.android.calculus.ComputedStat |
|
|
|
|
|
|
|
import net.pokeranalytics.android.calculus.Stat |
|
|
|
|
|
|
|
import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager |
|
|
|
import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager |
|
|
|
import net.pokeranalytics.android.calculus.optimalduration.CashGameOptimalDurationCalculator |
|
|
|
import net.pokeranalytics.android.calculus.optimalduration.CashGameOptimalDurationCalculator |
|
|
|
import net.pokeranalytics.android.exceptions.PAIllegalStateException |
|
|
|
import net.pokeranalytics.android.exceptions.PAIllegalStateException |
|
|
|
@ -39,17 +36,15 @@ import net.pokeranalytics.android.ui.modules.data.EditableDataActivity |
|
|
|
import net.pokeranalytics.android.ui.modules.datalist.DataListActivity |
|
|
|
import net.pokeranalytics.android.ui.modules.datalist.DataListActivity |
|
|
|
import net.pokeranalytics.android.ui.modules.handhistory.HandHistoryActivity |
|
|
|
import net.pokeranalytics.android.ui.modules.handhistory.HandHistoryActivity |
|
|
|
import net.pokeranalytics.android.ui.view.* |
|
|
|
import net.pokeranalytics.android.ui.view.* |
|
|
|
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable |
|
|
|
|
|
|
|
import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRow |
|
|
|
|
|
|
|
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow |
|
|
|
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow |
|
|
|
import net.pokeranalytics.android.util.Preferences |
|
|
|
import net.pokeranalytics.android.util.Preferences |
|
|
|
import net.pokeranalytics.android.util.extensions.* |
|
|
|
import net.pokeranalytics.android.util.extensions.* |
|
|
|
import timber.log.Timber |
|
|
|
import timber.log.Timber |
|
|
|
import java.util.* |
|
|
|
import java.util.* |
|
|
|
|
|
|
|
|
|
|
|
class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepresentableDataSource { |
|
|
|
class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepresentableDataSource, ResultCaptureTypeDelegate { |
|
|
|
|
|
|
|
|
|
|
|
private lateinit var viewModel: SessionViewModel |
|
|
|
private lateinit var model: SessionViewModel |
|
|
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
companion object { |
|
|
|
const val TIMER_DELAY = 60000L |
|
|
|
const val TIMER_DELAY = 60000L |
|
|
|
@ -91,7 +86,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
override fun onCreate(savedInstanceState: Bundle?) { |
|
|
|
override fun onCreate(savedInstanceState: Bundle?) { |
|
|
|
super.onCreate(savedInstanceState) |
|
|
|
super.onCreate(savedInstanceState) |
|
|
|
|
|
|
|
|
|
|
|
this.viewModel = activity?.run { |
|
|
|
this.model = activity?.run { |
|
|
|
ViewModelProvider(this).get(SessionViewModel::class.java) |
|
|
|
ViewModelProvider(this).get(SessionViewModel::class.java) |
|
|
|
} ?: throw Exception("Invalid Activity") |
|
|
|
} ?: throw Exception("Invalid Activity") |
|
|
|
|
|
|
|
|
|
|
|
@ -158,9 +153,10 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
override fun onOptionsItemSelected(item: MenuItem): Boolean { |
|
|
|
override fun onOptionsItemSelected(item: MenuItem): Boolean { |
|
|
|
when (item.itemId) { |
|
|
|
when (item.itemId) { |
|
|
|
R.id.stop -> stopSession() |
|
|
|
R.id.stop -> stopSession() |
|
|
|
R.id.newHandHistory -> addHandHistory() |
|
|
|
R.id.new_hand_history -> addHandHistory() |
|
|
|
R.id.newCustomField -> addNewCustomField() |
|
|
|
R.id.new_custom_field -> addNewCustomField() |
|
|
|
R.id.restart -> restartTimer() |
|
|
|
R.id.restart -> restartTimer() |
|
|
|
|
|
|
|
R.id.change_result_capture_method -> changeResultCaptureMethod() |
|
|
|
R.id.delete -> deleteSession() |
|
|
|
R.id.delete -> deleteSession() |
|
|
|
} |
|
|
|
} |
|
|
|
return true |
|
|
|
return true |
|
|
|
@ -170,13 +166,13 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
|
|
|
|
|
|
|
|
val realm = getRealm() |
|
|
|
val realm = getRealm() |
|
|
|
|
|
|
|
|
|
|
|
val sessionId = this.viewModel.sessionId |
|
|
|
val sessionId = this.model.sessionId |
|
|
|
if (sessionId != null) { |
|
|
|
if (sessionId != null) { |
|
|
|
|
|
|
|
|
|
|
|
val sessionRealm = realm.findById<Session>(sessionId) |
|
|
|
val sessionRealm = realm.findById<Session>(sessionId) |
|
|
|
if (sessionRealm != null) { |
|
|
|
if (sessionRealm != null) { |
|
|
|
|
|
|
|
|
|
|
|
if (this.viewModel.duplicate) { // duplicate session |
|
|
|
if (this.model.duplicate) { // duplicate session |
|
|
|
realm.executeTransaction { |
|
|
|
realm.executeTransaction { |
|
|
|
val session = sessionRealm.duplicate() |
|
|
|
val session = sessionRealm.duplicate() |
|
|
|
currentSession = session |
|
|
|
currentSession = session |
|
|
|
@ -191,7 +187,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
} |
|
|
|
} |
|
|
|
} else { // create new session |
|
|
|
} else { // create new session |
|
|
|
realm.executeTransaction { executeRealm -> |
|
|
|
realm.executeTransaction { executeRealm -> |
|
|
|
currentSession = Session.newInstance(executeRealm, this.viewModel.isTournament) |
|
|
|
currentSession = Session.newInstance(executeRealm, this.model.isTournament) |
|
|
|
FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, null, requireContext()) |
|
|
|
FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, null, requireContext()) |
|
|
|
} |
|
|
|
} |
|
|
|
// Find the nearest location around the user |
|
|
|
// Find the nearest location around the user |
|
|
|
@ -261,7 +257,11 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
when (row) { |
|
|
|
when (row) { |
|
|
|
SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT, |
|
|
|
SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT, |
|
|
|
SessionRow.BUY_IN, SessionRow.TIPS, SessionRow.START_DATE, |
|
|
|
SessionRow.BUY_IN, SessionRow.TIPS, SessionRow.START_DATE, |
|
|
|
SessionRow.END_DATE, SessionRow.BANKROLL, SessionRow.BREAK_TIME -> updateSessionUI() |
|
|
|
SessionRow.END_DATE, SessionRow.BREAK_TIME -> updateSessionUI() |
|
|
|
|
|
|
|
SessionRow.BANKROLL -> { |
|
|
|
|
|
|
|
updateSessionUI() |
|
|
|
|
|
|
|
updateMenuUI() // result capture method |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
@ -322,6 +322,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
* Update Menu UI |
|
|
|
* Update Menu UI |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private fun updateMenuUI() { |
|
|
|
private fun updateMenuUI() { |
|
|
|
|
|
|
|
|
|
|
|
when (currentSession.getState()) { |
|
|
|
when (currentSession.getState()) { |
|
|
|
SessionState.PENDING, SessionState.PLANNED -> { |
|
|
|
SessionState.PENDING, SessionState.PLANNED -> { |
|
|
|
sessionMenu?.findItem(R.id.restart)?.isVisible = false |
|
|
|
sessionMenu?.findItem(R.id.restart)?.isVisible = false |
|
|
|
@ -336,6 +337,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
sessionMenu?.findItem(R.id.stop)?.isVisible = false |
|
|
|
sessionMenu?.findItem(R.id.stop)?.isVisible = false |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
sessionMenu?.findItem(R.id.change_result_capture_method)?.isVisible = !this.currentSession.isLive |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -439,6 +441,15 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
updateSessionUI() |
|
|
|
updateSessionUI() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
|
|
|
|
* Shows result capture method popup |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private fun changeResultCaptureMethod() { |
|
|
|
|
|
|
|
val currentMethod = this.model.resultCaptureType ?: this.currentSession.bankroll?.resultCaptureType(requireContext()) |
|
|
|
|
|
|
|
val resultCaptureSelectionPopup = ResultCaptureSelectionPopup(this, currentMethod, requireActivity()) |
|
|
|
|
|
|
|
resultCaptureSelectionPopup.showAtLocation(this.view, Gravity.CENTER, 0, 0) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Delete a session |
|
|
|
* Delete a session |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@ -462,12 +473,11 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Static Data Source |
|
|
|
//// Static Data Source |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Override to surcharge custom field viewType |
|
|
|
// Override to surcharge custom field viewType |
|
|
|
override fun viewTypeForPosition(position: Int): Int { |
|
|
|
override fun viewTypeForPosition(position: Int): Int { |
|
|
|
rowRepresentationForCurrentState[position].let { |
|
|
|
this.model.rowForPosition(position).let { |
|
|
|
if (it is CustomField) { |
|
|
|
if (it is CustomField) { |
|
|
|
return RowViewType.TITLE_VALUE.ordinal |
|
|
|
return RowViewType.TITLE_VALUE.ordinal |
|
|
|
} |
|
|
|
} |
|
|
|
@ -475,87 +485,14 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
return super.viewTypeForPosition(position) |
|
|
|
return super.viewTypeForPosition(position) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun updateRowRepresentation() { |
|
|
|
@Ignore |
|
|
|
this.model.updatedRowRepresentationForCurrentState(this.currentSession, getRealm(), requireContext()) |
|
|
|
private var rowRepresentationForCurrentState: List<RowRepresentable> = mutableListOf() |
|
|
|
this.sessionAdapter.notifyDataSetChanged() |
|
|
|
|
|
|
|
// this.rowRepresentationForCurrentState = this.updatedRowRepresentationForCurrentState(requireContext()) |
|
|
|
private fun updatedRowRepresentationForCurrentState(context: Context): List<RowRepresentable> { |
|
|
|
|
|
|
|
val rows = ArrayList<RowRepresentable>() |
|
|
|
|
|
|
|
val session = this.currentSession |
|
|
|
|
|
|
|
val result = session.result |
|
|
|
|
|
|
|
val currency = session.currency |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Headers |
|
|
|
|
|
|
|
when (this.currentSession.getState()) { |
|
|
|
|
|
|
|
SessionState.STARTED -> { |
|
|
|
|
|
|
|
rows.add( |
|
|
|
|
|
|
|
CustomizableRowRepresentable( |
|
|
|
|
|
|
|
RowViewType.HEADER_TITLE_AMOUNT_BIG, |
|
|
|
|
|
|
|
title = session.getFormattedDuration(), |
|
|
|
|
|
|
|
valueTextFormat = ComputedStat(Stat.NET_RESULT, result?.net ?: 0.0, currency = session.currency).textFormat |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
rows.add(SeparatorRow()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
SessionState.PAUSED -> { |
|
|
|
|
|
|
|
rows.add( |
|
|
|
|
|
|
|
CustomizableRowRepresentable( |
|
|
|
|
|
|
|
RowViewType.HEADER_TITLE_AMOUNT_BIG, |
|
|
|
|
|
|
|
resId = R.string.pause, |
|
|
|
|
|
|
|
valueTextFormat = ComputedStat(Stat.NET_RESULT, result?.net ?: 0.0, currency = currency).textFormat |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
rows.add(SeparatorRow()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
SessionState.FINISHED -> { |
|
|
|
|
|
|
|
rows.add( |
|
|
|
|
|
|
|
CustomizableRowRepresentable( |
|
|
|
|
|
|
|
RowViewType.HEADER_TITLE_AMOUNT_BIG, |
|
|
|
|
|
|
|
title = session.getFormattedDuration(), |
|
|
|
|
|
|
|
valueTextFormat = ComputedStat(Stat.NET_RESULT, result?.net ?: 0.0, currency = currency).textFormat |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
rows.add( |
|
|
|
|
|
|
|
CustomizableRowRepresentable( |
|
|
|
|
|
|
|
RowViewType.HEADER_TITLE_AMOUNT, |
|
|
|
|
|
|
|
resId = R.string.hour_rate_without_pauses, |
|
|
|
|
|
|
|
valueTextFormat = ComputedStat(Stat.HOURLY_RATE, session.hourlyRate, currency = currency).textFormat |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (!isTournament()) { |
|
|
|
|
|
|
|
// rows.add( |
|
|
|
|
|
|
|
// CustomizableRowRepresentable( |
|
|
|
|
|
|
|
// RowViewType.HEADER_TITLE_VALUE, |
|
|
|
|
|
|
|
// resId = R.string.bankroll_variation, |
|
|
|
|
|
|
|
// computedStat = ComputedStat(Stat.HOURLY_RATE, 0.0, CurrencyUtils.getCurrency(bankroll)) |
|
|
|
|
|
|
|
// ) |
|
|
|
|
|
|
|
// ) |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
rows.add(SeparatorRow()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else -> { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Rows |
|
|
|
|
|
|
|
rows.addAll(SessionRow.getRows(this.currentSession, requireContext())) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add custom fields |
|
|
|
|
|
|
|
getRealm().let { |
|
|
|
|
|
|
|
rows.add(SeparatorRow()) |
|
|
|
|
|
|
|
rows.addAll(it.sorted<CustomField>()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return rows |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun updateRowRepresentation() { |
|
|
|
|
|
|
|
this.rowRepresentationForCurrentState = this.updatedRowRepresentationForCurrentState(requireContext()) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
override fun adapterRows(): List<RowRepresentable>? { |
|
|
|
override fun adapterRows(): List<RowRepresentable>? { |
|
|
|
return this.rowRepresentationForCurrentState |
|
|
|
return this.model.rows |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
override fun boolForRow(row: RowRepresentable): Boolean { |
|
|
|
override fun boolForRow(row: RowRepresentable): Boolean { |
|
|
|
@ -688,5 +625,26 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override fun resultCaptureTypeSelected(resultCaptureType: ResultCaptureType, applyBankroll: Boolean) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getRealm().executeTransaction { // cleanup existing results |
|
|
|
|
|
|
|
when (resultCaptureType) { |
|
|
|
|
|
|
|
ResultCaptureType.NET_RESULT -> { |
|
|
|
|
|
|
|
this.currentSession.clearBuyinCashedOut() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ResultCaptureType.BUYIN_CASHEDOUT -> { |
|
|
|
|
|
|
|
this.currentSession.clearNetResult() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.model.resultCaptureType = resultCaptureType |
|
|
|
|
|
|
|
if (applyBankroll) { |
|
|
|
|
|
|
|
this.currentSession.bankroll?.let { bankroll -> |
|
|
|
|
|
|
|
Preferences.setResultCaptureType(bankroll, resultCaptureType, requireContext()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.updateRowRepresentation() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |