diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 123dffcf..ebdad1b8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,120 +1,132 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + package="net.pokeranalytics.android"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index 5ca7c7f0..2ed38ca4 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -33,7 +33,7 @@ class PokerAnalyticsApplication : Application() { Realm.init(this) val realmConfiguration = RealmConfiguration.Builder() .name(Realm.DEFAULT_REALM_NAME) - .schemaVersion(5) + .schemaVersion(6) .migration(PokerAnalyticsMigration()) .initialData(Seed(this)) .build() diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index bb7b3ba4..0a8d1cb5 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -94,6 +94,18 @@ class PokerAnalyticsMigration : RealmMigration { currentVersion++ } + // Migrate to version 6 + if (currentVersion == 5) { + Timber.d("*** Running migration ${currentVersion + 1}") + schema.get("Transaction")?.let { + it.addField("dayOfWeek", Integer::class.java) + it.addField("month", Integer::class.java) + it.addField("year", Integer::class.java) + it.addField("dayOfMonth", Integer::class.java) + } + currentVersion++ + } + } override fun equals(other: Any?): Boolean { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt index 481a9444..d502df37 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt @@ -4,12 +4,14 @@ import io.realm.Realm import io.realm.RealmObject import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey +import io.realm.kotlin.where import net.pokeranalytics.android.R import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.interfaces.DatedValue import net.pokeranalytics.android.model.interfaces.Manageable import net.pokeranalytics.android.model.interfaces.SaveValidityStatus +import net.pokeranalytics.android.model.interfaces.TimeFilterable import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType @@ -18,9 +20,10 @@ import java.util.* import kotlin.collections.ArrayList -open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable, Filterable, DatedValue { +open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable, TimeFilterable, Filterable, DatedValue { companion object { + val rowRepresentation: List by lazy { val rows = ArrayList() rows.addAll(TransactionRow.values()) @@ -54,6 +57,12 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo // A user comment var comment: String = "" + // Timed interface + override var dayOfWeek: Int? = null + override var month: Int? = null + override var year: Int? = null + override var dayOfMonth: Int? = null + @Ignore override val viewType: Int = RowViewType.ROW_TRANSACTION.ordinal @@ -75,10 +84,6 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo return bankroll != null && type != null && amount != 0.0 } - override fun alreadyExists(realm: Realm): Boolean { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - override fun getFailedSaveMessage(status: SaveValidityStatus): Int { return if (bankroll == null) { R.string.no_br_popup_message @@ -89,6 +94,10 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo } } + override fun alreadyExists(realm: Realm): Boolean { + return realm.where().equalTo("id", id).findFirst()!= null + } + override fun isValidForDelete(realm: Realm): Boolean { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } @@ -97,4 +106,10 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } + override fun getSaveValidityStatus(realm: Realm): SaveValidityStatus { + if (bankroll == null || type == null || amount == 0.0) { + return SaveValidityStatus.DATA_INVALID + } + return SaveValidityStatus.VALID + } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt index a0d2d371..4139784e 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt @@ -3,6 +3,7 @@ package net.pokeranalytics.android.model.utils import android.content.Context import io.realm.Realm import io.realm.kotlin.where +import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.Currency import net.pokeranalytics.android.util.UserDefaults @@ -19,7 +20,7 @@ class Seed(var context:Context) : Realm.Transaction { } private fun createDefaultTournamentFeatures(realm: Realm) { - context.resources.getStringArray(net.pokeranalytics.android.R.array.seed_tournament_features).forEach { + context.resources.getStringArray(R.array.seed_tournament_features).forEach { val tournamentFeature = TournamentFeature() tournamentFeature.id = UUID.randomUUID().toString() tournamentFeature.name = it @@ -44,8 +45,8 @@ class Seed(var context:Context) : Realm.Transaction { } private fun createDefaultGames(realm: Realm) { - val gamesName = context.resources.getStringArray(net.pokeranalytics.android.R.array.seed_games) - val gamesShortName = context.resources.getStringArray(net.pokeranalytics.android.R.array.seed_games_short_name) + val gamesName = context.resources.getStringArray(R.array.seed_games) + val gamesShortName = context.resources.getStringArray(R.array.seed_games_short_name) for ((index, name) in gamesName.withIndex()) { val game = Game() game.id = UUID.randomUUID().toString() @@ -58,6 +59,11 @@ class Seed(var context:Context) : Realm.Transaction { private fun createDefaultTransactionTypes(realm: Realm) { TransactionType.Value.values().forEachIndexed { index, value -> val type = TransactionType() + type.name = when(value) { + TransactionType.Value.WITHDRAWAL -> context.getString(R.string.withdrawal) + TransactionType.Value.DEPOSIT -> context.getString(R.string.deposit) + TransactionType.Value.BONUS -> context.getString(R.string.bonus) + } type.additive = value.additive type.kind = index type.lock = true diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/BankrollDetailsActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/BankrollDetailsActivity.kt new file mode 100644 index 00000000..131192b3 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/BankrollDetailsActivity.kt @@ -0,0 +1,48 @@ +package net.pokeranalytics.android.ui.activity + +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.Fragment +import net.pokeranalytics.android.R +import net.pokeranalytics.android.calculus.bankroll.BankrollReport +import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity +import net.pokeranalytics.android.ui.fragment.BankrollDetailsFragment + +class BankrollDetailsActivity : PokerAnalyticsActivity() { + + companion object { + + private var bankrollReport: BankrollReport? = null + + /** + * Default constructor + */ + fun newInstanceForResult(fragment: Fragment, bankrollReport: BankrollReport, requestCode: Int) { + this.bankrollReport = bankrollReport + val intent = Intent(fragment.requireContext(), BankrollDetailsActivity::class.java) + fragment.startActivityForResult(intent, requestCode) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_bankroll_details) + initUI() + } + + /** + * Init UI + */ + private fun initUI() { + + bankrollReport?.let { + val fragmentTransaction = supportFragmentManager.beginTransaction() + val reportDetailsFragment = BankrollDetailsFragment.newInstance(it) + fragmentTransaction.add(R.id.container, reportDetailsFragment) + fragmentTransaction.commit() + + bankrollReport = null + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/EditableDataActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/EditableDataActivity.kt index fc9e305b..e1a34c27 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/EditableDataActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/EditableDataActivity.kt @@ -7,7 +7,7 @@ import androidx.fragment.app.Fragment import net.pokeranalytics.android.R import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity -import net.pokeranalytics.android.ui.fragment.BankrollDataFragment +import net.pokeranalytics.android.ui.fragment.BankrollEditDataFragment import net.pokeranalytics.android.ui.fragment.EditableDataFragment import net.pokeranalytics.android.ui.fragment.LocationDataFragment import net.pokeranalytics.android.ui.fragment.TransactionDataFragment @@ -62,7 +62,7 @@ class EditableDataActivity : PokerAnalyticsActivity() { val fragmentManager = supportFragmentManager val fragmentTransaction = fragmentManager.beginTransaction() val fragment: EditableDataFragment = when (dataType) { - LiveData.BANKROLL.ordinal -> BankrollDataFragment() + LiveData.BANKROLL.ordinal -> BankrollEditDataFragment() LiveData.LOCATION.ordinal -> LocationDataFragment() LiveData.TRANSACTION.ordinal -> TransactionDataFragment() else -> EditableDataFragment() diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt index 719b8249..e0289090 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt @@ -14,7 +14,6 @@ import kotlinx.android.synthetic.main.activity_home.* import net.pokeranalytics.android.BuildConfig import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.Currency -import net.pokeranalytics.android.ui.activity.FiltersActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.adapter.HomePagerAdapter import timber.log.Timber diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt new file mode 100644 index 00000000..38fbd3c7 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/NewDataMenuActivity.kt @@ -0,0 +1,127 @@ +package net.pokeranalytics.android.ui.activity + +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.view.View +import android.view.ViewAnimationUtils +import kotlinx.android.synthetic.main.activity_new_data.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity +import net.pokeranalytics.android.ui.extensions.px + + +class NewDataMenuActivity : PokerAnalyticsActivity() { + + enum class IntentKey(val keyName: String) { + CHOICE("CHOICE"), + } + + companion object { + fun newInstance(context: Context) { + val intent = Intent(context, NewDataMenuActivity::class.java) + context.startActivity(intent) + } + } + + private val fabSize = 48.px + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(net.pokeranalytics.android.R.layout.activity_new_data) + initUI() + } + + override fun onBackPressed() { + hideMenu() + } + + override fun onPause() { + super.onPause() + overridePendingTransition(0, 0) + } + + /** + * Init UI + */ + private fun initUI() { + + overridePendingTransition(0, 0) + + container.viewTreeObserver.addOnGlobalLayoutListener { + showMenu() + } + + newCashGame.setOnClickListener { + finishWithResult(0) + } + + newTournament.setOnClickListener { + finishWithResult(1) + } + + newTransaction.setOnClickListener { + finishWithResult(2) + } + + container.setOnClickListener { + hideMenu() + } + } + + /** + * Set the result and hide menu + */ + private fun finishWithResult(choice: Int) { + val intent = Intent() + intent.putExtra(IntentKey.CHOICE.keyName, choice) + setResult(RESULT_OK, intent) + GlobalScope.launch(Dispatchers.Main) { + delay(200) + hideMenu(true) + } + } + + /** + * Show menu + */ + private fun showMenu() { + + val cx = menuContainer.measuredWidth - fabSize / 2 + val cy = menuContainer.measuredHeight - fabSize / 2 + val finalRadius = Math.max(menuContainer.width, menuContainer.height) + val anim = ViewAnimationUtils.createCircularReveal(menuContainer, cx, cy, 0f, finalRadius.toFloat()) + anim.duration = 300 + + menuContainer.visibility = View.VISIBLE + anim.start() + } + + /** + * Hide menu + */ + private fun hideMenu(hideQuickly: Boolean = false) { + + val cx = menuContainer.measuredWidth - fabSize / 2 + val cy = menuContainer.measuredHeight - fabSize / 2 + val initialRadius = menuContainer.width + val anim = ViewAnimationUtils.createCircularReveal(menuContainer, cx, cy, initialRadius.toFloat(), 0f) + anim.duration = if (hideQuickly) 150 else 300 + + anim.addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator?) { + super.onAnimationEnd(animation) + menuContainer.visibility = View.INVISIBLE + finish() + } + }) + + anim.start() + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/ComparisonChartPagerAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/ComparisonChartPagerAdapter.kt index 1457bfb5..71bb2b84 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/ComparisonChartPagerAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/ComparisonChartPagerAdapter.kt @@ -8,7 +8,7 @@ import androidx.fragment.app.FragmentStatePagerAdapter import net.pokeranalytics.android.R import net.pokeranalytics.android.ui.fragment.CalendarFragment import net.pokeranalytics.android.ui.fragment.GraphFragment -import net.pokeranalytics.android.ui.fragment.HistoryFragment +import net.pokeranalytics.android.ui.fragment.FeedFragment import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import java.lang.ref.WeakReference @@ -24,7 +24,7 @@ class ComparisonChartPagerAdapter(val context: Context, fragmentManager: Fragmen 0 -> GraphFragment() 1 -> GraphFragment() 2 -> CalendarFragment.newInstance() - else -> HistoryFragment.newInstance() + else -> FeedFragment.newInstance() } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/HistorySessionRowRepresentableAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt similarity index 90% rename from app/src/main/java/net/pokeranalytics/android/ui/adapter/HistorySessionRowRepresentableAdapter.kt rename to app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt index 6e602693..c3ceb54a 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/HistorySessionRowRepresentableAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt @@ -7,7 +7,7 @@ import android.view.ViewGroup import androidx.appcompat.widget.AppCompatTextView import androidx.recyclerview.widget.RecyclerView import io.realm.RealmResults -import kotlinx.android.synthetic.main.row_history_session.view.* +import kotlinx.android.synthetic.main.row_feed_session.view.* import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.ui.view.BindableHolder @@ -24,7 +24,7 @@ import kotlin.collections.HashMap * @param dataSource the datasource providing rows * @param delegate the delegate, notified of UI actions */ -class HistorySessionRowRepresentableAdapter( +class FeedSessionRowRepresentableAdapter( var delegate: RowRepresentableDelegate? = null, var realmResults: RealmResults, var pendingRealmResults: RealmResults, @@ -43,7 +43,7 @@ class HistorySessionRowRepresentableAdapter( * Display a session view */ inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { - fun bind(position: Int, row: Session?, adapter: HistorySessionRowRepresentableAdapter) { + fun bind(position: Int, row: Session?, adapter: FeedSessionRowRepresentableAdapter) { itemView.sessionRow.setData(row as Session) val listener = View.OnClickListener { @@ -57,7 +57,7 @@ class HistorySessionRowRepresentableAdapter( * Display a session view */ inner class HeaderTitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { - fun bind(position: Int, title: String, adapter: HistorySessionRowRepresentableAdapter) { + fun bind(title: String) { // Title itemView.findViewById(R.id.title)?.let { it.text = title @@ -66,12 +66,12 @@ class HistorySessionRowRepresentableAdapter( } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - if (viewType == RowViewType.ROW_SESSION.ordinal) { - val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_history_session, parent, false) - return RowSessionViewHolder(layout) + return if (viewType == RowViewType.ROW_SESSION.ordinal) { + val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_feed_session, parent, false) + RowSessionViewHolder(layout) } else { val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_header_title, parent, false) - return HeaderTitleViewHolder(layout) + HeaderTitleViewHolder(layout) } } @@ -93,7 +93,7 @@ class HistorySessionRowRepresentableAdapter( if (holder is RowSessionViewHolder) { holder.bind(position, getSessionForPosition(position), this) } else if (holder is HeaderTitleViewHolder) { - holder.bind(position, getHeaderForPosition(holder.itemView.context, position), this) + holder.bind(getHeaderForPosition(holder.itemView.context, position)) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedTransactionRowRepresentableAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedTransactionRowRepresentableAdapter.kt new file mode 100644 index 00000000..603ebf33 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedTransactionRowRepresentableAdapter.kt @@ -0,0 +1,166 @@ +package net.pokeranalytics.android.ui.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.widget.AppCompatTextView +import androidx.recyclerview.widget.RecyclerView +import io.realm.RealmResults +import kotlinx.android.synthetic.main.row_transaction.view.* +import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.realm.Transaction +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.* +import kotlin.collections.HashMap + + +/** + * An adapter capable of displaying a list of RowRepresentables + * @param dataSource the datasource providing rows + * @param delegate the delegate, notified of UI actions + */ +class FeedTransactionRowRepresentableAdapter( + var delegate: RowRepresentableDelegate? = null, + var realmTransactions: RealmResults, + var distinctTransactionsHeaders: RealmResults +) : + RecyclerView.Adapter() { + + private var headersPositions = HashMap() + private lateinit var sortedHeaders: SortedMap + + init { + refreshData() + } + + /** + * Display a transaction view + */ + inner class RowTransactionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + fun bind(position: Int, row: Transaction?, adapter: FeedTransactionRowRepresentableAdapter) { + + itemView.transactionRow.setData(row as Transaction) + val listener = View.OnClickListener { + adapter.delegate?.onRowSelected(position, row) + } + itemView.transactionRow.setOnClickListener(listener) + } + } + + /** + * Display a header + */ + inner class HeaderTitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + fun bind(title: String) { + // Title + itemView.findViewById(R.id.title)?.let { + it.text = title + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return if (viewType == RowViewType.ROW_TRANSACTION.ordinal) { + val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_transaction, parent, false) + RowTransactionViewHolder(layout) + } else { + val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_header_title, parent, false) + HeaderTitleViewHolder(layout) + } + + } + + + override fun getItemViewType(position: Int): Int { + if (sortedHeaders.containsKey(position)) { + return RowViewType.HEADER_TITLE.ordinal + } else { + return RowViewType.ROW_TRANSACTION.ordinal + } + } + + override fun getItemCount(): Int { + return realmTransactions.size + distinctTransactionsHeaders.size + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder is RowTransactionViewHolder) { + holder.bind(position, getTransactionForPosition(position), this) + } else if (holder is HeaderTitleViewHolder) { + holder.bind(getHeaderForPosition(position)) + } + } + + /** + * Return the header + */ + private fun getHeaderForPosition(position: Int): String { + if (sortedHeaders.containsKey(position)) { + val realmHeaderPosition = sortedHeaders.keys.indexOf(position) + return distinctTransactionsHeaders[realmHeaderPosition]?.date?.getMonthAndYear() ?: "" + } + return NULL_TEXT + } + + /** + * Get real index + */ + private fun getTransactionForPosition(position: Int): Transaction? { + + // Row position + var headersBefore = 0 + for (key in sortedHeaders.keys) { + if (position > key) { + headersBefore++ + } else { + break + } + } + + return realmTransactions[position - headersBefore] + } + + /** + * Refresh headers positions + */ + fun refreshData() { + + headersPositions.clear() + + val start = System.currentTimeMillis() + + 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, transaction) in realmTransactions.withIndex()) { + calendar.time = transaction.date + if (checkHeaderCondition(calendar, previousYear, previousMonth)) { + headersPositions[index + headersPositions.size] = transaction.date + previousYear = calendar.get(Calendar.YEAR) + previousMonth = calendar.get(Calendar.MONTH) + } + } + + sortedHeaders = headersPositions.toSortedMap() + + 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/adapter/HomePagerAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/HomePagerAdapter.kt index f749a4db..22cd2c57 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/HomePagerAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/HomePagerAdapter.kt @@ -17,12 +17,12 @@ class HomePagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAda override fun getItem(position: Int): PokerAnalyticsFragment { return when (position) { - 0 -> HistoryFragment.newInstance() + 0 -> FeedFragment.newInstance() 1 -> StatisticsFragment.newInstance() 2 -> CalendarFragment.newInstance() 3 -> ReportsFragment.newInstance() 4 -> MoreFragment.newInstance() - else -> HistoryFragment.newInstance() + else -> FeedFragment.newInstance() } } @@ -43,7 +43,7 @@ class HomePagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAda override fun getItemPosition(obj: Any): Int { return when (obj) { - HistoryFragment::class.java -> 0 + FeedFragment::class.java -> 0 StatisticsFragment::class.java -> 1 CalendarFragment::class.java -> 2 ReportsFragment::class.java -> 3 diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt new file mode 100644 index 00000000..c2a49935 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDetailsFragment.kt @@ -0,0 +1,166 @@ +package net.pokeranalytics.android.ui.fragment + +import android.app.Activity.RESULT_OK +import android.content.Intent +import android.os.Bundle +import android.view.* +import androidx.recyclerview.widget.LinearLayoutManager +import kotlinx.android.synthetic.main.fragment_bankroll.* +import kotlinx.android.synthetic.main.fragment_stats.recyclerView +import net.pokeranalytics.android.R +import net.pokeranalytics.android.calculus.ComputedStat +import net.pokeranalytics.android.calculus.Stat +import net.pokeranalytics.android.calculus.bankroll.BankrollReport +import net.pokeranalytics.android.model.LiveData +import net.pokeranalytics.android.ui.activity.DataListActivity +import net.pokeranalytics.android.ui.activity.EditableDataActivity +import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity +import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter +import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate +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.CustomizableRowRepresentable + +class BankrollDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { + + companion object { + + const val REQUEST_CODE_EDIT = 1000 + + /** + * Create new instance + */ + fun newInstance(bankrollReport: BankrollReport): BankrollDetailsFragment { + val fragment = BankrollDetailsFragment() + fragment.bankrollReport = bankrollReport + return fragment + } + } + + private lateinit var parentActivity: PokerAnalyticsActivity + private lateinit var bankrollAdapter: RowRepresentableAdapter + private lateinit var bankrollReport: BankrollReport + + private var bankrollDetailsMenu: Menu? = null + private var rows: ArrayList = ArrayList() + + // Life Cycle + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fragment_bankroll_details, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initUI() + initData() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == REQUEST_CODE_EDIT && resultCode == RESULT_OK) { + if (data != null && data.getBooleanExtra(DataListActivity.IntentKey.ITEM_DELETED.keyName, false)) { + activity?.setResult(RESULT_OK, data) + activity?.finish() + } else { + updateMenuUI() + } + } + } + + override fun adapterRows(): List? { + return rows + } + + override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { + + } + + override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { + menu?.clear() + inflater?.inflate(R.menu.toolbar_comparison_chart, menu) + this.bankrollDetailsMenu = menu + updateMenuUI() + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + when (item!!.itemId) { + R.id.settings -> editBankroll() + } + return true + } + + // Business + + /** + * Init data + */ + private fun initData() { + + rows.clear() + + rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.global)) + + val totalComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.total) + val netComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.netResult) + val netBankedComputedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.netBanked) + + rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE, resId = R.string.bankroll, computedStat = totalComputedStat)) + rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE, resId = R.string.net_result, computedStat = netComputedStat)) + rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE, resId = R.string.net_banked, computedStat = netBankedComputedStat)) + + } + + /** + * Init UI + */ + private fun initUI() { + + parentActivity = activity as PokerAnalyticsActivity + + // Avoid a bug during setting the title + toolbar.title = "" + + parentActivity.setSupportActionBar(toolbar) + parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true) + setHasOptionsMenu(true) + updateMenuUI() + + bankrollAdapter = RowRepresentableAdapter(this, this) + + val viewManager = LinearLayoutManager(requireContext()) + + recyclerView.apply { + setHasFixedSize(true) + layoutManager = viewManager + adapter = bankrollAdapter + } + } + + /** + * Update menu UI + */ + private fun updateMenuUI() { + if (bankrollReport.setup.virtualBankroll) { + toolbar.title = getString(R.string.total) + collapsingToolbar.title = getString(R.string.total) + bankrollDetailsMenu?.findItem(R.id.settings)?.isVisible = false + } else { + toolbar.title = bankrollReport.setup.bankroll?.name + collapsingToolbar.title = bankrollReport.setup.bankroll?.name + bankrollDetailsMenu?.findItem(R.id.settings)?.isVisible = true + } + + } + + /** + * Open Bankroll edit activity + */ + private fun editBankroll() { + EditableDataActivity.newInstanceForResult(this, LiveData.BANKROLL.ordinal, bankrollReport.setup.bankroll?.id, REQUEST_CODE_EDIT) + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollEditDataFragment.kt similarity index 94% rename from app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt rename to app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollEditDataFragment.kt index 7f15c747..67947540 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollEditDataFragment.kt @@ -3,6 +3,8 @@ package net.pokeranalytics.android.ui.fragment import android.app.Activity.RESULT_OK import android.content.Intent import android.os.Bundle +import android.view.Menu +import android.view.MenuInflater import android.view.View import net.pokeranalytics.android.R import net.pokeranalytics.android.api.CurrencyConverterApi @@ -30,7 +32,7 @@ import java.util.* /** * Custom EditableDataFragment to manage the Bankroll data */ -class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataSource { +class BankrollEditDataFragment : EditableDataFragment(), StaticRowRepresentableDataSource { companion object { const val REQUEST_CODE_CURRENCY: Int = 100 @@ -54,6 +56,11 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS } ?: false } + override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { + super.onCreateOptionsMenu(menu, inflater) + menu?.findItem(R.id.delete)?.isVisible = false + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -130,7 +137,7 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { when (row) { - BankrollRow.CURRENCY -> CurrenciesActivity.newInstanceForResult(this@BankrollDataFragment, REQUEST_CODE_CURRENCY) + BankrollRow.CURRENCY -> CurrenciesActivity.newInstanceForResult(this@BankrollEditDataFragment, REQUEST_CODE_CURRENCY) BankrollRow.REFRESH_RATE -> refreshRate() else -> super.onRowSelected(position, row, fromAction) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt index dd25a45f..442c6bab 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt @@ -6,7 +6,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.appcompat.app.AlertDialog import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.Snackbar import io.realm.Realm @@ -22,16 +21,14 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import net.pokeranalytics.android.R -import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.bankroll.BankrollCalculator import net.pokeranalytics.android.calculus.bankroll.BankrollReport import net.pokeranalytics.android.calculus.bankroll.BankrollReportSetup -import net.pokeranalytics.android.model.Criteria import net.pokeranalytics.android.model.LiveData -import net.pokeranalytics.android.model.interfaces.Deletable import net.pokeranalytics.android.model.realm.Bankroll +import net.pokeranalytics.android.ui.activity.BankrollDetailsActivity import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.EditableDataActivity import net.pokeranalytics.android.ui.activity.StatisticDetailsActivity @@ -39,8 +36,6 @@ import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource -import net.pokeranalytics.android.ui.extensions.toast -import net.pokeranalytics.android.ui.fragment.DataListFragment.Companion.REQUEST_CODE_DETAILS import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType @@ -54,6 +49,8 @@ class BankrollFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSou companion object { + const val REQUEST_CODE_DETAILS = 1000 + /** * Create new instance */ @@ -98,6 +95,9 @@ class BankrollFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSou } } } + + initData() + //TODO: Refresh bankroll } override fun adapterRows(): List? { @@ -105,17 +105,22 @@ class BankrollFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSou } override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { - Timber.d("onRowSelected: $row") - when(row) { + when (row) { is GraphRow -> { - row.report.results.firstOrNull()?.group?.let { computableGroup -> - StatisticDetailsActivity.newInstance(requireContext(), row.stat, computableGroup, row.report, false, row.title) + row.report?.let { report -> + row.stat?.let { stat -> + report.results.firstOrNull()?.group?.let { computableGroup -> + StatisticDetailsActivity.newInstance(requireContext(), stat, computableGroup, report, false, row.title) + } + } } } else -> { if (bankrollReportForRow.containsKey(row)) { - val bankrollReport = bankrollReportForRow[row] - toast("${bankrollReport?.total}") + bankrollReportForRow[row]?.let { bankrollReport -> + lastItemClickedPosition = position + BankrollDetailsActivity.newInstanceForResult(this, bankrollReport, REQUEST_CODE_DETAILS) + } } } } @@ -137,41 +142,32 @@ class BankrollFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSou val realm = Realm.getDefaultInstance() // Graph - - val requiredStats: List = listOf(Stat.NET_RESULT) - val options = Calculator.Options( - evolutionValues = Calculator.Options.EvolutionValues.STANDARD, - stats = requiredStats, - criterias = listOf(Criteria.Bankrolls) - ) - - val report = Calculator.computeStats(realm, options = options) - rows.add(0, GraphRow(report, Stat.NET_RESULT)) - val globalBankrollReportSetup = BankrollReportSetup() val globalBankrollReport = BankrollCalculator.computeReport(globalBankrollReportSetup) + rows.add(0, GraphRow(dataSet = globalBankrollReport.lineDataSet(requireContext()))) rows.add(globalBankrollReport) bankrollReportForRow[globalBankrollReport] = globalBankrollReport // Bankrolls rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.bankrolls)) - val bankrolls = LiveData.BANKROLL.items(realm) as RealmResults - - bankrolls.forEach { - val bankrollReportSetup = BankrollReportSetup(it) - val bankrollReport = BankrollCalculator.computeReport(bankrollReportSetup) - val computedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.total) - val row = CustomizableRowRepresentable(RowViewType.TITLE_VALUE_ARROW, title = it.name, computedStat = computedStat, isSelectable = true) - - rows.add(row) - bankrollReportForRow[row] = bankrollReport - } - realm.close() Timber.d("initData: ${System.currentTimeMillis() - startDate.time}ms") launch(Dispatchers.Main) { + + val bankrolls = LiveData.BANKROLL.items(getRealm()) as RealmResults + + bankrolls.forEach { + val bankrollReportSetup = BankrollReportSetup(it) + val bankrollReport = BankrollCalculator.computeReport(bankrollReportSetup) + val computedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.total) + val row = CustomizableRowRepresentable(RowViewType.TITLE_VALUE_ARROW, title = it.name, computedStat = computedStat, isSelectable = true) + + rows.add(row) + bankrollReportForRow[row] = bankrollReport + } + if (!isDetached) { bankrollAdapter.notifyDataSetChanged() } @@ -218,32 +214,41 @@ class BankrollFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSou */ private fun deleteItem(position: Int) { + //TODO: Get bankroll from bankrollReport and delete it + + /* if (isDetached || activity == null) { return } // Save the delete position & create a copy of the object - val mRecentlyDeletedItem = rowRepresentableForPosition(position) + var mRecentlyDeletedItem = rowRepresentableForPosition(position) lastDeletedItemPosition = position - if (mRecentlyDeletedItem is RealmObject) { - // Check if the object is valid for the deletion - if ((mRecentlyDeletedItem as Deletable).isValidForDelete(this.getRealm())) { - deletedItem = getRealm().copyFromRealm(mRecentlyDeletedItem) - getRealm().executeTransaction { - mRecentlyDeletedItem.deleteFromRealm() + if (mRecentlyDeletedItem is BankrollReport) { + + if (mRecentlyDeletedItem is RealmObject) { + // Check if the object is valid for the deletion + if ((mRecentlyDeletedItem as Deletable).isValidForDelete(this.getRealm())) { + deletedItem = getRealm().copyFromRealm(mRecentlyDeletedItem) + getRealm().executeTransaction { + mRecentlyDeletedItem.deleteFromRealm() + } + bankrollAdapter.notifyItemRemoved(position) + showUndoSnackBar() + } else { + bankrollAdapter.notifyItemChanged(position) + val builder = AlertDialog.Builder(requireContext()) + .setMessage((mRecentlyDeletedItem as Deletable).getFailedDeleteMessage()) + .setNegativeButton(R.string.ok, null) + builder.show() } - bankrollAdapter.notifyItemRemoved(position) - showUndoSnackBar() - } else { - bankrollAdapter.notifyItemChanged(position) - val builder = AlertDialog.Builder(requireContext()) - .setMessage((mRecentlyDeletedItem as Deletable).getFailedDeleteMessage()) - .setNegativeButton(R.string.ok, null) - builder.show() } + } + */ + } /** diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt index ebb162b8..d8ae4772 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt @@ -150,8 +150,12 @@ class CalendarDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { when (row) { is GraphRow -> { - row.report.results.firstOrNull()?.group?.let { computableGroup -> - StatisticDetailsActivity.newInstance(requireContext(), row.stat, computableGroup, row.report, false, row.title) + row.report?.let { report -> + row.stat?.let { stat -> + report.results.firstOrNull()?.group?.let { computableGroup -> + StatisticDetailsActivity.newInstance(requireContext(), stat, computableGroup, report, false, row.title) + } + } } } } @@ -199,7 +203,8 @@ class CalendarDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable val options = Calculator.Options( evolutionValues = Calculator.Options.EvolutionValues.STANDARD, stats = requiredStats, - query = query) + query = query + ) val report = Calculator.computeStats(realm, options) Timber.d("Report take: ${System.currentTimeMillis() - startDate.time}ms") @@ -207,17 +212,27 @@ class CalendarDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable report.results.firstOrNull()?.let { // Create rows + val dataSet1 = report.results.firstOrNull()?.defaultStatEntries(Stat.NET_RESULT, requireContext()) + val dataSet2 = report.results.firstOrNull()?.defaultStatEntries(Stat.STANDARD_DEVIATION, requireContext()) + val dataSet3 = report.results.firstOrNull()?.defaultStatEntries(Stat.HOURLY_DURATION, requireContext()) rowRepresentables.clear() rowRepresentables.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.net_result)) - rowRepresentables.add(GraphRow(report, Stat.NET_RESULT)) + rowRepresentables.add(GraphRow(dataSet1, report = report, stat = Stat.NET_RESULT)) rowRepresentables.add(StatDoubleRow(it.computedStat(Stat.NET_RESULT), it.computedStat(Stat.HOURLY_RATE))) rowRepresentables.add(StatDoubleRow(it.computedStat(Stat.LOCATIONS_PLAYED), it.computedStat(Stat.LONGEST_STREAKS))) rowRepresentables.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.distribution)) - rowRepresentables.add(GraphRow(report, Stat.STANDARD_DEVIATION, requireContext().getString(R.string.distribution))) + rowRepresentables.add( + GraphRow( + dataSet2, + requireContext().getString(R.string.distribution), + report = report, + stat = Stat.STANDARD_DEVIATION + ) + ) rowRepresentables.add(StatDoubleRow(it.computedStat(Stat.WIN_RATIO), it.computedStat(Stat.MAXIMUM_NETRESULT))) rowRepresentables.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.volume)) - rowRepresentables.add(GraphRow(report, Stat.HOURLY_DURATION)) + rowRepresentables.add(GraphRow(dataSet3, report = report, stat = Stat.HOURLY_DURATION)) rowRepresentables.add(StatDoubleRow(it.computedStat(Stat.HOURLY_DURATION), it.computedStat(Stat.AVERAGE_HOURLY_DURATION))) rowRepresentables.add(StatDoubleRow(it.computedStat(Stat.DAYS_PLAYED), it.computedStat(Stat.MAXIMUM_DURATION))) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt new file mode 100644 index 00000000..00405ddf --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -0,0 +1,192 @@ +package net.pokeranalytics.android.ui.fragment + +import android.app.Activity.RESULT_OK +import android.content.Intent +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.core.app.ActivityOptionsCompat +import androidx.core.view.isVisible +import androidx.interpolator.view.animation.FastOutSlowInInterpolator +import io.realm.RealmResults +import io.realm.Sort +import io.realm.kotlin.where +import kotlinx.android.synthetic.main.fragment_feed.* +import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.LiveData +import net.pokeranalytics.android.model.interfaces.Editable +import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.model.realm.Transaction +import net.pokeranalytics.android.ui.activity.EditableDataActivity +import net.pokeranalytics.android.ui.activity.NewDataMenuActivity +import net.pokeranalytics.android.ui.activity.SessionActivity +import net.pokeranalytics.android.ui.adapter.FeedSessionRowRepresentableAdapter +import net.pokeranalytics.android.ui.adapter.FeedTransactionRowRepresentableAdapter +import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate +import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment +import net.pokeranalytics.android.ui.view.RowRepresentable +import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager +import net.pokeranalytics.android.util.Preferences +import java.text.SimpleDateFormat +import java.util.* + + + + + +class FeedFragment : PokerAnalyticsFragment(), RowRepresentableDelegate { + + companion object { + + const val REQUEST_CODE_MENU = 100 + + fun newInstance(): FeedFragment { + val fragment = FeedFragment() + val bundle = Bundle() + fragment.arguments = bundle + return fragment + } + } + + private lateinit var feedSessionAdapter: FeedSessionRowRepresentableAdapter + private lateinit var feedTransactionAdapter: FeedTransactionRowRepresentableAdapter + private lateinit var realmSessions: RealmResults + private lateinit var realmTransactions: RealmResults + private lateinit var betaLimitDate: Date + + private var newSessionCreated: Boolean = false + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fragment_feed, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initUI() + initData() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == REQUEST_CODE_MENU && resultCode == RESULT_OK && data != null) { + when(data.getIntExtra(NewDataMenuActivity.IntentKey.CHOICE.keyName, -1)) { + 0 -> createNewSession(false) + 1 -> createNewSession(true) + 2 -> createNewTransaction() + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + realmSessions.removeAllChangeListeners() + } + + override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { + when(row) { + is Session -> SessionActivity.newInstance(requireContext(), sessionId = (row as Editable).id) + is Transaction -> EditableDataActivity.newInstance(requireContext(), LiveData.TRANSACTION.ordinal, row.id) + } + } + + /** + * Init UI + */ + private fun initUI() { + + disclaimerContainer.isVisible = Preferences.shouldShowDisclaimer(requireContext()) + + disclaimerDismiss.setOnClickListener { + Preferences.setStopShowingDisclaimer(requireContext()) + + disclaimerContainer.animate().translationY(disclaimerContainer.height.toFloat()) + .setInterpolator(FastOutSlowInInterpolator()) + .withEndAction { disclaimerContainer?.isVisible = false } + .start() + } + + addButton.setOnClickListener { + activity?.let { + val options = ActivityOptionsCompat.makeSceneTransitionAnimation(it) + val intent = Intent(requireContext(), NewDataMenuActivity::class.java) + startActivityForResult(intent, REQUEST_CODE_MENU, options.toBundle()) + } + } + + filterSessions.setOnClickListener { + recyclerView.adapter = this.feedSessionAdapter + } + + filterTransactions.setOnClickListener { + recyclerView.adapter = this.feedTransactionAdapter + } + + } + + /** + * Init data + */ + private fun initData() { + + val sdf = SimpleDateFormat("dd/M/yyyy hh:mm", Locale.getDefault()) + betaLimitDate = sdf.parse("17/7/2019 10:00") + + this.realmSessions = getRealm().where().findAll().sort("startDate", Sort.DESCENDING) + this.realmSessions.addChangeListener { _, _ -> + this.feedSessionAdapter.refreshData() + this.feedSessionAdapter.notifyDataSetChanged() + } + + 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) + this.feedSessionAdapter = FeedSessionRowRepresentableAdapter(this, realmSessions, pendingSessions, distinctDateSessions) + + this.realmTransactions = getRealm().where().findAll().sort("date", Sort.DESCENDING) + val distinctDateTransactions = getRealm().where().distinct("year", "month").findAll().sort("date", Sort.DESCENDING) + this.feedTransactionAdapter = FeedTransactionRowRepresentableAdapter(this, realmTransactions, distinctDateTransactions) + + val viewManager = SmoothScrollLinearLayoutManager(requireContext()) + recyclerView.apply { + setHasFixedSize(true) + layoutManager = viewManager + adapter = feedSessionAdapter + } + } + + /** + * Create a new cash game + */ + private fun createNewSession(isTournament: Boolean) { + + if (Date().after(betaLimitDate)) { + this.showEndOfBetaMessage() + return + } + + SessionActivity.newInstance(requireContext(), isTournament) + newSessionCreated = true + } + + /** + * Create a new transaction + */ + private fun createNewTransaction() { + + if (Date().after(betaLimitDate)) { + this.showEndOfBetaMessage() + return + } + + EditableDataActivity.newInstance(requireContext(), LiveData.TRANSACTION.ordinal) + } + + /** + * Show end of beta message + */ + private fun showEndOfBetaMessage() { + Toast.makeText(context, "Beta has ended. Please update with the Google Play version", Toast.LENGTH_LONG).show() + } + +} \ 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 deleted file mode 100644 index 06319966..00000000 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt +++ /dev/null @@ -1,152 +0,0 @@ -package net.pokeranalytics.android.ui.fragment - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Toast -import androidx.core.view.isVisible -import androidx.interpolator.view.animation.FastOutSlowInInterpolator -import io.realm.RealmResults -import io.realm.Sort -import io.realm.kotlin.where -import kotlinx.android.synthetic.main.fragment_history.* -import net.pokeranalytics.android.R -import net.pokeranalytics.android.model.interfaces.Editable -import net.pokeranalytics.android.model.realm.Session -import net.pokeranalytics.android.ui.activity.SessionActivity -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 -import net.pokeranalytics.android.ui.view.RowRepresentable -import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager -import net.pokeranalytics.android.util.Preferences -import java.text.SimpleDateFormat -import java.util.* - -class HistoryFragment : PokerAnalyticsFragment(), LiveRowRepresentableDataSource, RowRepresentableDelegate { - - companion object { - fun newInstance(): HistoryFragment { - val fragment = HistoryFragment() - val bundle = Bundle() - fragment.arguments = bundle - return fragment - } - } - - private lateinit var historyAdapter: HistorySessionRowRepresentableAdapter - - private lateinit var realmSessions: RealmResults - private val rows: ArrayList = ArrayList() - private var newSessionCreated: Boolean = false - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_history, container, false) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - initUI() - initData() - } - - override fun onDestroyView() { - super.onDestroyView() - realmSessions.removeAllChangeListeners() - } - - /** - * Init UI - */ - private fun initUI() { - - disclaimerContainer.isVisible = Preferences.shouldShowDisclaimer(requireContext()) - - val sdf = SimpleDateFormat("dd/M/yyyy hh:mm") - val betaLimitDate = sdf.parse("17/7/2019 10:00") - - newCashGame.setOnClickListener { - - if (Date().after(betaLimitDate)) { - this.showEndOfBetaMessage() - return@setOnClickListener - } - - SessionActivity.newInstance(requireContext(), false) - newSessionCreated = true - } - - newTournament.setOnClickListener { - - if (Date().after(betaLimitDate)) { - this.showEndOfBetaMessage() - return@setOnClickListener - } - - SessionActivity.newInstance(requireContext(), true) - newSessionCreated = true - } - - disclaimerDismiss.setOnClickListener { - Preferences.setStopShowingDisclaimer(requireContext()) - - disclaimerContainer.animate().translationY(disclaimerContainer.height.toFloat()) - .setInterpolator(FastOutSlowInInterpolator()) - .withEndAction { disclaimerContainer?.isVisible = false } - .start() - } - - } - - private fun showEndOfBetaMessage() { - Toast.makeText(context, "Beta has ended. Please update with the Google Play version", Toast.LENGTH_LONG).show() - - } - - /** - * Init data - */ - private fun initData() { - - this.realmSessions = getRealm().where().findAll().sort("startDate", Sort.DESCENDING) - this.realmSessions.addChangeListener { _, _ -> - this.historyAdapter.refreshData() - this.historyAdapter.notifyDataSetChanged() - } - - 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) - - this.historyAdapter = HistorySessionRowRepresentableAdapter(this, startedSessions, pendingSessions, distinctDateSessions) - - val viewManager = SmoothScrollLinearLayoutManager(requireContext()) - recyclerView.apply { - setHasFixedSize(true) - layoutManager = viewManager - adapter = historyAdapter - } - } - - override fun rowRepresentableForPosition(position: Int): RowRepresentable? { - return this.rows[position] - } - - override fun numberOfRows(): Int { - return this.rows.size - } - - override fun viewTypeForPosition(position: Int): Int { - return rows[position].viewType - } - - override fun indexForRow(row: RowRepresentable): Int { - return this.rows.indexOf(row) - } - - override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { - SessionActivity.newInstance(requireContext(), sessionId = (row as Editable).id) - } -} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index 05c5d691..d80eb28b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -314,13 +314,13 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate { realm.commitTransaction() // Find the nearest location around the user - parentActivity.findNearestLocation { location -> - location?.let { + parentActivity.findNearestLocation { + it?.let { location -> realm.beginTransaction() - val location = realm.where().equalTo("id", it.id).findFirst() - FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, location, requireContext()) + val realmLocation = realm.where().equalTo("id", location.id).findFirst() + FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, realmLocation, requireContext()) - currentSession.location = location + currentSession.location = realmLocation realm.commitTransaction() updateSessionUI(true) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetType.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetType.kt index 41ce26f5..447453b0 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetType.kt @@ -1,33 +1,48 @@ package net.pokeranalytics.android.ui.fragment.components.bottomsheet enum class BottomSheetType { - NONE { override fun newInstance() = BottomSheetFragment()}, - LIST { override fun newInstance() = BottomSheetListFragment()}, - LIST_STATIC { override fun newInstance() = BottomSheetStaticListFragment()}, - LIST_GAME { override fun newInstance() = BottomSheetListGameFragment()}, - DOUBLE_LIST { override fun newInstance() = BottomSheetListGameFragment()}, - MULTI_SELECTION { override fun newInstance() = BottomSheetMultiSelectionFragment()}, - GRID { override fun newInstance() = BottomSheetTableSizeGridFragment()}, - EDIT_TEXT { override fun newInstance() = BottomSheetEditTextFragment()}, - EDIT_TEXT_MULTI_LINES { override fun newInstance() = BottomSheetEditTextMultiLinesFragment()}, - DOUBLE_EDIT_TEXT { override fun newInstance() = BottomSheetDoubleEditTextFragment()}, - NUMERIC_TEXT { override fun newInstance() = BottomSheetNumericTextFragment()}, - SUM { override fun newInstance() = BottomSheetSumFragment()}; + NONE, + LIST, + LIST_STATIC, + LIST_GAME, + DOUBLE_LIST, + MULTI_SELECTION, + GRID, + EDIT_TEXT, + EDIT_TEXT_MULTI_LINES, + DOUBLE_EDIT_TEXT, + NUMERIC_TEXT, + SUM; - abstract fun newInstance(): BottomSheetFragment + fun newInstance(): BottomSheetFragment { + return when (this) { + NONE -> BottomSheetFragment() + LIST -> BottomSheetListFragment() + LIST_STATIC -> BottomSheetStaticListFragment() + LIST_GAME -> BottomSheetListGameFragment() + DOUBLE_LIST -> BottomSheetListGameFragment() + MULTI_SELECTION -> BottomSheetMultiSelectionFragment() + GRID -> BottomSheetTableSizeGridFragment() + EDIT_TEXT -> BottomSheetEditTextFragment() + EDIT_TEXT_MULTI_LINES -> BottomSheetEditTextMultiLinesFragment() + DOUBLE_EDIT_TEXT -> BottomSheetDoubleEditTextFragment() + NUMERIC_TEXT -> BottomSheetNumericTextFragment() + SUM -> BottomSheetSumFragment() + } + } - val validationRequired : Boolean - get() = when (this) { - LIST, LIST_GAME, LIST_STATIC, GRID, DOUBLE_LIST -> false - else -> true - } + val validationRequired: Boolean + get() = when (this) { + LIST, LIST_GAME, LIST_STATIC, GRID, DOUBLE_LIST -> false + else -> true + } - val clearRequired : Boolean - get() = true + val clearRequired: Boolean + get() = true - val addRequired : Boolean - get() = when (this) { - EDIT_TEXT, NUMERIC_TEXT, DOUBLE_EDIT_TEXT, EDIT_TEXT_MULTI_LINES, GRID, LIST_STATIC, SUM -> false - else -> true - } + val addRequired: Boolean + get() = when (this) { + EDIT_TEXT, NUMERIC_TEXT, DOUBLE_EDIT_TEXT, EDIT_TEXT_MULTI_LINES, GRID, LIST_STATIC, SUM -> false + else -> true + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/HistorySessionDiffCallback.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/HistorySessionDiffCallback.kt index 09ecd30a..df0ff0b3 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/HistorySessionDiffCallback.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/HistorySessionDiffCallback.kt @@ -35,11 +35,7 @@ class HistorySessionDiffCallback(var newRows: List, var oldRow // Force to update all the rows that were already there if (oldRows[oldItemPosition] is Session && newRows[newItemPosition] is Session) { - val session1 = oldRows[oldItemPosition] as Session - val session2 = newRows[newItemPosition] as Session - - return false //session1.id == session2.id - + return false } else if (oldRows[oldItemPosition] is CustomizableRowRepresentable && newRows[newItemPosition] is CustomizableRowRepresentable) { val header1 = oldRows[oldItemPosition] as CustomizableRowRepresentable val header2 = newRows[newItemPosition] as CustomizableRowRepresentable diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index 05c518f4..f4c6a62f 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -17,7 +17,7 @@ import com.github.mikephil.charting.data.BarData import com.github.mikephil.charting.data.BarDataSet import com.github.mikephil.charting.data.LineData import com.github.mikephil.charting.data.LineDataSet -import kotlinx.android.synthetic.main.row_history_session.view.* +import kotlinx.android.synthetic.main.row_feed_session.view.* import kotlinx.android.synthetic.main.row_transaction.view.* import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.ComputedStat @@ -71,7 +71,7 @@ enum class RowViewType(private var layoutRes: Int) { LOADER(R.layout.row_loader), // Custom row - ROW_SESSION(R.layout.row_history_session), + ROW_SESSION(R.layout.row_feed_session), ROW_TRANSACTION(R.layout.row_transaction), ROW_BUTTON(R.layout.row_button), ROW_FOLLOW_US(R.layout.row_follow_us), @@ -93,7 +93,7 @@ enum class RowViewType(private var layoutRes: Int) { return when (this) { // Row View Holder - HEADER_TITLE, HEADER_TITLE_VALUE, HEADER_TITLE_AMOUNT, HEADER_TITLE_AMOUNT_BIG, LOCATION_TITLE, + HEADER_TITLE, HEADER_TITLE_VALUE, HEADER_TITLE_AMOUNT, HEADER_TITLE_AMOUNT_BIG, LOCATION_TITLE, INFO, TITLE, TITLE_ARROW, TITLE_ICON_ARROW, TITLE_VALUE, TITLE_VALUE_ARROW, TITLE_GRID, TITLE_SWITCH, TITLE_CHECK, TITLE_VALUE_CHECK, DATA, BOTTOM_SHEET_DATA, LOADER -> RowViewHolder(layout) @@ -126,6 +126,7 @@ enum class RowViewType(private var layoutRes: Int) { /** * Display a generic row (title, value, container) */ + @SuppressWarnings("ResourceType") inner class RowViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) { @@ -319,7 +320,7 @@ enum class RowViewType(private var layoutRes: Int) { if (row is GraphRow) { - row.report.results.firstOrNull()?.defaultStatEntries(row.stat, itemView.context)?.let { dataSet -> + row.dataSet?.let { dataSet -> val context = itemView.context diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt index fc9b1c39..40db96da 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt @@ -26,7 +26,7 @@ import net.pokeranalytics.android.util.extensions.toCurrency */ class SessionRowView : FrameLayout { - private lateinit var rowHistorySession: ConstraintLayout + private lateinit var rowSession: ConstraintLayout /** * Constructors @@ -48,9 +48,9 @@ class SessionRowView : FrameLayout { */ private fun init() { val layoutInflater = LayoutInflater.from(context) - rowHistorySession = layoutInflater.inflate(R.layout.row_session_view, this, false) as ConstraintLayout + rowSession = layoutInflater.inflate(R.layout.row_session_view, this, false) as ConstraintLayout val layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT) - addView(rowHistorySession, layoutParams) + addView(rowSession, layoutParams) } /** @@ -61,8 +61,8 @@ class SessionRowView : FrameLayout { val date = session.startDate ?: session.creationDate // Date - rowHistorySession.dateDay.text = date.getShortDayName() - rowHistorySession.dateNumber.text = date.getDayNumber() + rowSession.dateDay.text = date.getShortDayName() + rowSession.dateNumber.text = date.getDayNumber() // Title / Game type @@ -99,60 +99,55 @@ class SessionRowView : FrameLayout { } val title = parameters.joinToString(separator = " ") - rowHistorySession.sessionTitle.text = title + rowSession.sessionTitle.text = title // Duration -// rowHistorySession.sessionInfoDurationIcon.isVisible = session.timeFrame != null -// rowHistorySession.sessionInfoDurationValue.isVisible = session.timeFrame != null -// session.timeFrame?.let { -// rowHistorySession.sessionInfoDurationValue.text = session.getFormattedDuration() -// } - rowHistorySession.sessionInfoDurationValue.text = session.getFormattedDuration() + rowSession.sessionInfoDurationValue.text = session.getFormattedDuration() // Location - rowHistorySession.sessionInfoLocationIcon.isVisible = session.location != null - rowHistorySession.sessionInfoLocationValue.isVisible = session.location != null + rowSession.sessionInfoLocationIcon.isVisible = session.location != null + rowSession.sessionInfoLocationValue.isVisible = session.location != null session.location?.let { - rowHistorySession.sessionInfoLocationValue.text = it.name + rowSession.sessionInfoLocationValue.text = it.name } // Table size - rowHistorySession.sessionInfoTableIcon.isVisible = session.tableSize != null - rowHistorySession.sessionInfoTableValue.isVisible = session.tableSize != null + rowSession.sessionInfoTableIcon.isVisible = session.tableSize != null + rowSession.sessionInfoTableValue.isVisible = session.tableSize != null session.tableSize?.let { - rowHistorySession.sessionInfoTableValue.text = TableSize(it).localizedTitle(context) + rowSession.sessionInfoTableValue.text = TableSize(it).localizedTitle(context) } val state = session.getState() - rowHistorySession.sessionInfoDurationIcon.isVisible = state.hasStarted - rowHistorySession.sessionInfoDurationValue.isVisible = state.hasStarted + rowSession.sessionInfoDurationIcon.isVisible = state.hasStarted + rowSession.sessionInfoDurationValue.isVisible = state.hasStarted // State if (state == SessionState.STARTED) { - rowHistorySession.gameResult.isVisible = false - rowHistorySession.infoIcon.isVisible = true - rowHistorySession.infoIcon.setImageResource(R.drawable.chip) - rowHistorySession.infoTitle.isVisible = true - rowHistorySession.infoTitle.text = context.getString(R.string.running_session_state) + rowSession.gameResult.isVisible = false + rowSession.infoIcon.isVisible = true + rowSession.infoIcon.setImageResource(R.drawable.chip) + rowSession.infoTitle.isVisible = true + rowSession.infoTitle.text = context.getString(R.string.running_session_state) } else if (state == SessionState.PLANNED) { - rowHistorySession.gameResult.isVisible = false - rowHistorySession.infoIcon.isVisible = true - rowHistorySession.infoIcon.setImageResource(R.drawable.ic_planned) - rowHistorySession.infoTitle.isVisible = true - rowHistorySession.infoTitle.text = session.startDate!!.shortTime() + rowSession.gameResult.isVisible = false + rowSession.infoIcon.isVisible = true + rowSession.infoIcon.setImageResource(R.drawable.ic_planned) + rowSession.infoTitle.isVisible = true + rowSession.infoTitle.text = session.startDate!!.shortTime() } else if (state == SessionState.PENDING) { - rowHistorySession.gameResult.isVisible = false - rowHistorySession.infoIcon.isVisible = false - rowHistorySession.infoTitle.isVisible = false + rowSession.gameResult.isVisible = false + rowSession.infoIcon.isVisible = false + rowSession.infoTitle.isVisible = false } else { - rowHistorySession.gameResult.isVisible = true - rowHistorySession.infoIcon.isVisible = false - rowHistorySession.infoTitle.isVisible = false + rowSession.gameResult.isVisible = true + rowSession.infoIcon.isVisible = false + rowSession.infoTitle.isVisible = false val result = session.result?.net ?: 0.0 val formattedStat = ComputedStat(Stat.NET_RESULT, result, currency = session.currency).format() - rowHistorySession.gameResult.setTextFormat(formattedStat, context) + rowSession.gameResult.setTextFormat(formattedStat, context) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/GraphRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/GraphRow.kt index b877e42e..7af17e6b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/GraphRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/GraphRow.kt @@ -1,12 +1,13 @@ package net.pokeranalytics.android.ui.view.rowrepresentable +import com.github.mikephil.charting.data.DataSet import net.pokeranalytics.android.calculus.Report import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType -class GraphRow(var report: Report, var stat: Stat, var title: String? = null) : RowRepresentable { +class GraphRow(var dataSet: DataSet<*>?, var title: String? = null, var report: Report? = null, var stat: Stat? = null) : RowRepresentable { override val viewType: Int get() = RowViewType.GRAPH.ordinal diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/DateExtension.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/DateExtension.kt index b60ba293..8efb3739 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/extensions/DateExtension.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/DateExtension.kt @@ -95,7 +95,6 @@ fun Date.getMonthAndYear(): String { // Return the netDuration between two dates fun Date.getFormattedDuration(toDate: Date) : String { val difference = (toDate.time - this.time).toInt() - val numOfDays = (difference / (1000 * 60 * 60 * 24)) val hours = (difference / (1000 * 60 * 60)) val minutes = (difference / (1000 * 60)) % 60 diff --git a/app/src/main/res/layout/activity_bankroll_details.xml b/app/src/main/res/layout/activity_bankroll_details.xml new file mode 100644 index 00000000..70454fb9 --- /dev/null +++ b/app/src/main/res/layout/activity_bankroll_details.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_new_data.xml b/app/src/main/res/layout/activity_new_data.xml new file mode 100644 index 00000000..cc84d52f --- /dev/null +++ b/app/src/main/res/layout/activity_new_data.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_bankroll_details.xml b/app/src/main/res/layout/fragment_bankroll_details.xml new file mode 100644 index 00000000..0cf1c9b1 --- /dev/null +++ b/app/src/main/res/layout/fragment_bankroll_details.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_history.xml b/app/src/main/res/layout/fragment_feed.xml similarity index 58% rename from app/src/main/res/layout/fragment_history.xml rename to app/src/main/res/layout/fragment_feed.xml index 6177771c..fda9a9ef 100644 --- a/app/src/main/res/layout/fragment_history.xml +++ b/app/src/main/res/layout/fragment_feed.xml @@ -7,49 +7,66 @@ android:layout_height="match_parent" tools:context=".ui.activity.HomeActivity"> - + app:layout_constraintTop_toTopOf="parent"> - + + + + + + + + + + + + + + + + app:layout_constraintTop_toBottomOf="@+id/appBar" + tools:listitem="@layout/row_feed_session" /> + + diff --git a/app/src/main/res/layout/row_history_session.xml b/app/src/main/res/layout/row_feed_session.xml similarity index 100% rename from app/src/main/res/layout/row_history_session.xml rename to app/src/main/res/layout/row_feed_session.xml diff --git a/app/src/main/res/menu/toolbar_bankroll_details.xml b/app/src/main/res/menu/toolbar_bankroll_details.xml new file mode 100644 index 00000000..2132026e --- /dev/null +++ b/app/src/main/res/menu/toolbar_bankroll_details.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d58f7de3..49ebcaa0 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -11,6 +11,7 @@ @color/colorPrimary @color/white @color/white + true @style/PokerAnalyticsTheme.BottomNavigationView @style/PokerAnalyticsTheme.Toolbar @@ -23,6 +24,7 @@ + @@ -241,6 +243,17 @@ + +