Add Top 10 view

feature/top10
Aurelien Hubert 7 years ago
parent 5b7d8ab2b9
commit c1d271b495
  1. 5
      app/src/main/AndroidManifest.xml
  2. 42
      app/src/main/java/net/pokeranalytics/android/model/extensions/SessionExtensions.kt
  3. 33
      app/src/main/java/net/pokeranalytics/android/ui/activity/Top10Activity.kt
  4. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/MoreFragment.kt
  5. 154
      app/src/main/java/net/pokeranalytics/android/ui/fragment/Top10Fragment.kt
  6. 47
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  7. 39
      app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt
  8. 3
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/MoreTabRow.kt
  9. 5
      app/src/main/res/drawable/ic_outline_star.xml
  10. 15
      app/src/main/res/layout/activity_top_10.xml
  11. 71
      app/src/main/res/layout/fragment_top_10.xml
  12. 71
      app/src/main/res/layout/row_top_10.xml
  13. 16
      app/src/main/res/values/styles.xml

@ -74,6 +74,11 @@
android:launchMode="singleTop"
android:screenOrientation="portrait" />
<activity
android:name="net.pokeranalytics.android.ui.activity.Top10Activity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
<activity
android:name="net.pokeranalytics.android.ui.activity.SettingsActivity"
android:launchMode="singleTop"

@ -1,6 +1,10 @@
package net.pokeranalytics.android.model.extensions
import android.content.Context
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.TournamentType
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.util.extensions.toCurrency
import java.util.*
enum class SessionState {
@ -39,7 +43,45 @@ fun Session.getState(): SessionState {
return SessionState.STARTED
}
}
}
/**
* Formate the session game type
*/
fun Session.getFormattedGameType(context: Context): String {
var parameters = mutableListOf<String>()
if (isTournament()) {
tournamentEntryFee?.let {
parameters.add(it.toCurrency(currency))
}
tournamentName?.let {
parameters.add(it.name)
} ?: run {
parameters.add(getFormattedGame())
tournamentType?.let { type ->
parameters.add(TournamentType.values()[type].localizedTitle(context))
}
}
if (parameters.size == 0) {
parameters.add(context.getString(R.string.tournament).capitalize())
}
} else {
if (cgSmallBlind != null && cgBigBlind != null) {
parameters.add(getFormattedBlinds())
}
game?.let {
parameters.add(getFormattedGame())
}
if (parameters.size == 0) {
parameters.add(context.getString(R.string.cash_game).capitalize())
}
}
return parameters.joinToString(separator = " ")
}
val AbstractList<Session>.hourlyDuration: Double

@ -0,0 +1,33 @@
package net.pokeranalytics.android.ui.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
class Top10Activity : PokerAnalyticsActivity() {
companion object {
fun newInstance(context: Context) {
val intent = Intent(context, Top10Activity::class.java)
context.startActivity(intent)
}
/**
* Create a new instance for result
*/
fun newInstanceForResult(fragment: Fragment, requestCode: Int) {
val intent = Intent(fragment.requireContext(), Top10Activity::class.java)
fragment.startActivityForResult(intent, requestCode)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_top_10)
}
}

@ -9,6 +9,7 @@ import kotlinx.android.synthetic.main.fragment_more.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.BankrollActivity
import net.pokeranalytics.android.ui.activity.SettingsActivity
import net.pokeranalytics.android.ui.activity.Top10Activity
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
@ -62,6 +63,7 @@ class MoreFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSource,
super.onRowSelected(position, row, fromAction)
when(row) {
MoreTabRow.BANKROLL -> BankrollActivity.newInstance(requireContext())
MoreTabRow.TOP_10 -> Top10Activity.newInstance(requireContext())
MoreTabRow.SETTINGS -> SettingsActivity.newInstance(requireContext())
}
}

@ -0,0 +1,154 @@
package net.pokeranalytics.android.ui.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.tabs.TabLayout
import io.realm.RealmModel
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.realm.Session
import net.pokeranalytics.android.model.realm.Transaction
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager
class Top10Fragment : RealmFragment(), RowRepresentableDataSource, RowRepresentableDelegate {
private enum class Tab {
CASH_GAMES,
TOURNAMENTS
}
companion object {
fun newInstance(): Top10Fragment {
val fragment = Top10Fragment()
val bundle = Bundle()
fragment.arguments = bundle
return fragment
}
}
private lateinit var dataListAdapter: RowRepresentableAdapter
private lateinit var realmCashGames: RealmResults<Session>
private lateinit var realmTournaments: RealmResults<Session>
private var currentTab: Tab = Tab.CASH_GAMES
override val observedEntities: List<Class<out RealmModel>> = listOf(Session::class.java, Transaction::class.java)
override fun entitiesChanged(clazz: Class<out RealmModel>) {
super.entitiesChanged(clazz)
when (clazz.kotlin) {
Session::class -> {
this.dataListAdapter.notifyDataSetChanged()
}
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_top_10, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
initData()
}
override fun adapterRows(): List<RowRepresentable>? {
return when (currentTab) {
Tab.CASH_GAMES -> realmCashGames
Tab.TOURNAMENTS -> realmTournaments
}
}
override fun rowRepresentableForPosition(position: Int): RowRepresentable? {
return when (currentTab) {
Tab.CASH_GAMES -> realmCashGames[position]
Tab.TOURNAMENTS -> realmTournaments[position]
}
}
override fun numberOfRows(): Int {
return when (currentTab) {
Tab.CASH_GAMES -> realmCashGames.size
Tab.TOURNAMENTS -> realmTournaments.size
}
}
override fun viewTypeForPosition(position: Int): Int {
return RowViewType.ROW_TOP_10.ordinal
}
/**
* Init UI
*/
private fun initUI() {
setDisplayHomeAsUpEnabled(true)
tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
when (tab.position) {
0 -> {
currentTab = Tab.CASH_GAMES
dataListAdapter.notifyDataSetChanged()
}
1 -> {
currentTab = Tab.TOURNAMENTS
}
}
dataListAdapter.notifyDataSetChanged()
}
override fun onTabUnselected(tab: TabLayout.Tab) {
}
override fun onTabReselected(tab: TabLayout.Tab) {
}
})
val viewManager = SmoothScrollLinearLayoutManager(requireContext())
recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
}
}
/**
* Init data
*/
private fun initData() {
this.realmCashGames = getRealm().where<Session>()
.equalTo("type", Session.Type.CASH_GAME.ordinal)
.greaterThanOrEqualTo("result.net", 0.0)
.sort("result.net", Sort.DESCENDING)
.limit(10)
.findAll()
this.realmTournaments = getRealm().where<Session>()
.equalTo("type", Session.Type.TOURNAMENT.ordinal)
.greaterThanOrEqualTo("result.net", 0.0)
.sort("result.net", Sort.DESCENDING)
.limit(10)
.findAll()
dataListAdapter = RowRepresentableAdapter(this, this)
recyclerView.adapter = dataListAdapter
}
}

@ -26,6 +26,7 @@ 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.extensions.getFormattedGameType
import net.pokeranalytics.android.model.realm.CustomField
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.Transaction
@ -37,6 +38,7 @@ import net.pokeranalytics.android.ui.extensions.setTextFormat
import net.pokeranalytics.android.ui.graph.AxisFormatting
import net.pokeranalytics.android.ui.graph.setStyle
import net.pokeranalytics.android.ui.view.rowrepresentable.*
import net.pokeranalytics.android.util.extensions.longDate
/**
* An interface used to factor the configuration of RecyclerView.ViewHolder
@ -78,6 +80,7 @@ enum class RowViewType(private var layoutRes: Int) {
// Custom row
ROW_SESSION(R.layout.row_feed_session),
ROW_TRANSACTION(R.layout.row_transaction),
ROW_TOP_10(R.layout.row_top_10),
ROW_BUTTON(R.layout.row_button),
ROW_FOLLOW_US(R.layout.row_follow_us),
STATS(R.layout.row_stats_title_value),
@ -110,6 +113,10 @@ enum class RowViewType(private var layoutRes: Int) {
// Row Transaction
ROW_TRANSACTION -> RowTransactionViewHolder(layout)
// Row Transaction
ROW_TOP_10 -> RowTop10ViewHolder(layout)
// Row Button
ROW_BUTTON -> RowButtonViewHolder(layout)
@ -513,6 +520,46 @@ enum class RowViewType(private var layoutRes: Int) {
}
}
/**
* Display a top 10 row
*/
inner class RowTop10ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
if (row is Session) {
itemView.findViewById<AppCompatTextView>(R.id.gameResult)?.let { gameResult ->
val result = row.result?.net ?: 0.0
val formattedStat = ComputedStat(Stat.NET_RESULT, result, currency = row.currency).format()
gameResult.setTextFormat(formattedStat, itemView.context)
}
itemView.findViewById<AppCompatTextView>(R.id.top10ResultPart1)?.let { part1 ->
part1.text = row.getFormattedGameType(itemView.context)
}
itemView.findViewById<AppCompatTextView>(R.id.top10ResultPart2)?.let { part2 ->
var content = row.getFormattedDuration()
if (!row.location?.name.isNullOrEmpty()) {
content += " - " + row.location?.name
} else if (!row.bankroll?.name.isNullOrEmpty()) {
content += " - " + row.bankroll?.name
}
part2.text = content
}
itemView.findViewById<AppCompatTextView>(R.id.top10ResultPart3)?.let { part3 ->
part3.text = row.creationDate.longDate()
}
}
}
}
/**
* Display a separator
*/

@ -11,15 +11,14 @@ import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.TableSize
import net.pokeranalytics.android.model.TournamentType
import net.pokeranalytics.android.model.extensions.SessionState
import net.pokeranalytics.android.model.extensions.getFormattedGameType
import net.pokeranalytics.android.model.extensions.getState
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.extensions.setTextFormat
import net.pokeranalytics.android.util.extensions.getDayNumber
import net.pokeranalytics.android.util.extensions.getShortDayName
import net.pokeranalytics.android.util.extensions.shortTime
import net.pokeranalytics.android.util.extensions.toCurrency
/**
* Display a row session
@ -65,41 +64,7 @@ class SessionRowView : FrameLayout {
rowSession.dateNumber.text = date.getDayNumber()
// Title / Game type
var parameters = mutableListOf<String>()
if (session.isTournament()) {
session.tournamentEntryFee?.let {
parameters.add(it.toCurrency(session.currency))
}
session.tournamentName?.let {
parameters.add(it.name)
} ?: run {
parameters.add(session.getFormattedGame())
session.tournamentType?.let { type ->
parameters.add(TournamentType.values()[type].localizedTitle(context))
}
}
if (parameters.size == 0) {
parameters.add(context.getString(R.string.tournament).capitalize())
}
} else {
if (session.cgSmallBlind != null && session.cgBigBlind != null) {
parameters.add(session.getFormattedBlinds())
}
session.game?.let {
parameters.add(session.getFormattedGame())
}
if (parameters.size == 0) {
parameters.add(context.getString(R.string.cash_game).capitalize())
}
}
val title = parameters.joinToString(separator = " ")
rowSession.sessionTitle.text = title
rowSession.sessionTitle.text = session.getFormattedGameType(context)
// Duration
rowSession.sessionInfoDurationValue.text = session.getFormattedDuration()

@ -9,12 +9,14 @@ import net.pokeranalytics.android.ui.view.RowViewType
*/
enum class MoreTabRow : RowRepresentable {
BANKROLL,
TOP_10,
SETTINGS;
override val resId: Int?
get() {
return when(this) {
BANKROLL -> R.string.bankroll
TOP_10 -> R.string.top_10
SETTINGS -> R.string.services
}
}
@ -23,6 +25,7 @@ enum class MoreTabRow : RowRepresentable {
get() {
return when(this) {
BANKROLL -> R.drawable.ic_outline_lock
TOP_10 -> R.drawable.ic_outline_star
SETTINGS -> R.drawable.ic_outline_settings
}
}

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z"/>
</vector>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<fragment
android:id="@+id/top10Fragment"
android:name="net.pokeranalytics.android.ui.fragment.Top10Fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/fragment_session" />
</LinearLayout>

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.activity.HomeActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:theme="@style/PokerAnalyticsTheme.Toolbar.Session"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:title="@string/top_10" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed">
<com.google.android.material.tabs.TabItem
android:id="@+id/filterSessions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cash_games" />
<com.google.android.material.tabs.TabItem
android:id="@+id/filterTransactions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tournaments" />
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/selectedFilter"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appBar" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/selectedFilter"
tools:listitem="@layout/row_top_10" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/gameResult"
style="@style/PokerAnalyticsTheme.TextView.Top10Row.Result"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:gravity="center"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="$ 1000" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/top10ResultPart1"
style="@style/PokerAnalyticsTheme.TextView.Top10Row"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/gameResult"
app:layout_constraintVertical_chainStyle="packed"
tools:text="$300 NL Hold'em" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/top10ResultPart2"
style="@style/PokerAnalyticsTheme.TextView.Top10Row"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/top10ResultPart1"
app:layout_constraintVertical_chainStyle="packed"
tools:text="10:30 - Hollywood Park" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/top10ResultPart3"
style="@style/PokerAnalyticsTheme.TextView.Top10Row"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/top10ResultPart2"
app:layout_constraintVertical_chainStyle="packed"
tools:text="July 22th, 2019" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -228,6 +228,22 @@
<item name="android:textColor">@color/green</item>
</style>
<!-- Top 10 Row -->
<style name="PokerAnalyticsTheme.TextView.Top10Row">
<item name="android:textColor">@color/white</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">@font/roboto</item>
</style>
<style name="PokerAnalyticsTheme.TextView.Top10Row.Result">
<item name="android:textSize">32sp</item>
<item name="android:fontFamily">@font/roboto_light</item>
<item name="android:textColor">@color/green</item>
</style>
<!-- Button Row -->

Loading…
Cancel
Save