Added ability to duplicate a session

csv
Laurent 6 years ago
parent 9fe135e17e
commit 05afd66d73
  1. 18
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  2. 27
      app/src/main/java/net/pokeranalytics/android/ui/activity/SessionActivity.kt
  3. 19
      app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt
  4. 43
      app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt
  5. 26
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt
  6. 38
      app/src/main/java/net/pokeranalytics/android/ui/view/ContextMenuRecyclerView.kt
  7. 3
      app/src/main/res/layout/fragment_feed.xml
  8. 1
      app/src/main/res/layout/row_bottom_sheet_grid_title.xml
  9. 3
      app/src/main/res/layout/row_session_view.xml
  10. 2
      app/src/main/res/layout/row_title.xml
  11. 2
      app/src/main/res/layout/row_title_arrow.xml
  12. 2
      app/src/main/res/layout/row_title_check.xml
  13. 2
      app/src/main/res/layout/row_title_icon_arrow.xml
  14. 8
      app/src/main/res/menu/menu_session.xml
  15. 7
      app/src/main/res/values/styles.xml

@ -658,6 +658,24 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
}
fun duplicate() : Session {
val copy = Session.newInstance(this.realm, this.isTournament(), this.bankroll)
copy.game = this.game
copy.limit = this.limit
copy.cgSmallBlind = this.cgSmallBlind
copy.cgBigBlind = this.cgBigBlind
copy.tournamentEntryFee = this.tournamentEntryFee
copy.tournamentFeatures = this.tournamentFeatures
copy.tournamentName = this.tournamentName
copy.tournamentType = this.tournamentType
copy.tableSize = this.tableSize
copy.numberOfTables = this.numberOfTables
return copy
}
@Ignore
override val viewType: Int = RowViewType.ROW_SESSION.ordinal

@ -14,32 +14,32 @@ class SessionActivity: PokerAnalyticsActivity() {
enum class IntentKey(val keyName : String) {
IS_TOURNAMENT("IS_TOURNAMENT"),
DUPLICATE("DUPLICATE"),
SESSION_ID("SESSION_ID");
}
companion object {
fun newInstance(context: Context, isTournament: Boolean? = false, sessionId: String? = "") {
val intent = Intent(context, SessionActivity::class.java)
isTournament?.let {
intent.putExtra(IntentKey.IS_TOURNAMENT.keyName, isTournament)
}
sessionId?.let {
intent.putExtra(IntentKey.SESSION_ID.keyName, sessionId)
}
fun newInstance(context: Context, isTournament: Boolean? = false, sessionId: String? = "", duplicate: Boolean = false) {
val intent = this.intent(context, isTournament, sessionId, duplicate)
context.startActivity(intent)
}
fun newInstanceforResult(fragment: Fragment, isTournament: Boolean? = false, sessionId: String? = "", requestCode: Int) {
val intent = Intent(fragment.requireContext(), SessionActivity::class.java)
fun newInstanceforResult(fragment: Fragment, isTournament: Boolean? = false, sessionId: String? = "", duplicate: Boolean = false, requestCode: Int) {
val intent = this.intent(fragment.requireContext(), isTournament, sessionId, duplicate)
fragment.startActivityForResult(intent, requestCode)
}
private fun intent(context: Context, isTournament: Boolean? = false, sessionId: String? = "", duplicate: Boolean = false) : Intent {
val intent = Intent(context, SessionActivity::class.java)
isTournament?.let {
intent.putExtra(IntentKey.IS_TOURNAMENT.keyName, isTournament)
}
intent.putExtra(IntentKey.DUPLICATE.keyName, duplicate)
sessionId?.let {
intent.putExtra(IntentKey.SESSION_ID.keyName, sessionId)
}
fragment.startActivityForResult(intent, requestCode)
return intent
}
}
@ -62,8 +62,9 @@ class SessionActivity: PokerAnalyticsActivity() {
private fun initUI() {
val sessionId = intent.getStringExtra(IntentKey.SESSION_ID.keyName)
val isTournament = intent.getBooleanExtra(IntentKey.IS_TOURNAMENT.keyName, false)
val duplicate = intent.getBooleanExtra(IntentKey.DUPLICATE.keyName, false)
val fragment = sessionFragment as SessionFragment
fragment.setData(isTournament, sessionId)
fragment.setData(isTournament, sessionId, duplicate)
}
}

@ -8,7 +8,6 @@ import androidx.appcompat.widget.AppCompatTextView
import androidx.recyclerview.widget.RecyclerView
import io.realm.RealmResults
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
import net.pokeranalytics.android.ui.view.RowViewType
@ -43,6 +42,7 @@ class FeedSessionRowRepresentableAdapter(
* Display a session view
*/
inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
fun bind(position: Int, row: Session?, adapter: FeedSessionRowRepresentableAdapter) {
itemView.sessionRow.setData(row as Session)
@ -50,6 +50,10 @@ class FeedSessionRowRepresentableAdapter(
adapter.delegate?.onRowSelected(position, row)
}
itemView.sessionRow.setOnClickListener(listener)
itemView.sessionRow.setOnLongClickListener {
itemView.showContextMenu()
}
}
}
@ -59,7 +63,7 @@ class FeedSessionRowRepresentableAdapter(
inner class HeaderTitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
fun bind(title: String) {
// Title
itemView.findViewById<AppCompatTextView>(R.id.title)?.let {
itemView.findViewById<AppCompatTextView>(net.pokeranalytics.android.R.id.title)?.let {
it.text = title
}
}
@ -67,10 +71,10 @@ class FeedSessionRowRepresentableAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == RowViewType.ROW_SESSION.ordinal) {
val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_feed_session, parent, false)
val layout = LayoutInflater.from(parent.context).inflate(net.pokeranalytics.android.R.layout.row_feed_session, parent, false)
RowSessionViewHolder(layout)
} else {
val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_header_title, parent, false)
val layout = LayoutInflater.from(parent.context).inflate(net.pokeranalytics.android.R.layout.row_header_title, parent, false)
HeaderTitleViewHolder(layout)
}
@ -104,7 +108,7 @@ class FeedSessionRowRepresentableAdapter(
// If the header has no date, it's a pending session
return if (sortedHeaders[position] == null) {
context.getString(R.string.pending)
context.getString(net.pokeranalytics.android.R.string.pending)
} else {
// Else, return the formatted date
val realmHeaderPosition = if (pendingRealmResults.size > 0) sortedHeaders.keys.indexOf(position) - 1 else sortedHeaders.keys.indexOf(position)
@ -114,6 +118,11 @@ class FeedSessionRowRepresentableAdapter(
return NULL_TEXT
}
fun sessionIdForPosition(position: Int): String? {
val session = this.getSessionForPosition(position)
return session?.id
}
/**
* Get real index
*/

@ -3,9 +3,7 @@ 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.view.*
import android.widget.Toast
import androidx.core.app.ActivityOptionsCompat
import androidx.core.view.isVisible
@ -17,6 +15,7 @@ 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.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.interfaces.Editable
import net.pokeranalytics.android.model.realm.Filter
@ -30,13 +29,14 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.FilterableFragment
import net.pokeranalytics.android.ui.interfaces.FilterActivityRequestCode
import net.pokeranalytics.android.ui.interfaces.FilterableType
import net.pokeranalytics.android.ui.view.ContextMenuRecyclerView
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager
import net.pokeranalytics.android.util.Preferences
import timber.log.Timber
import java.text.SimpleDateFormat
import java.util.*
class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
private enum class Tab {
@ -91,6 +91,35 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
return inflater.inflate(R.layout.fragment_feed, container, false)
}
override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
super.onCreateContextMenu(menu, v, menuInfo)
if (v?.id == R.id.recyclerView) {
activity?.menuInflater?.inflate(R.menu.menu_session, menu)
}
}
override fun onContextItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.duplicate -> {
val info = item.menuInfo as ContextMenuRecyclerView.RecyclerViewContextMenuInfo
Timber.d("info = $info")
val sessionId = this.feedSessionAdapter.sessionIdForPosition(info.position)
if (sessionId != null) {
createNewSession(true, sessionId = sessionId, duplicate = true)
} else {
throw PAIllegalStateException("Session not found for duplicate at position: ${info.position}")
}
}
else -> { }
}
return true
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initUI()
@ -160,6 +189,8 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
*/
private fun initUI() {
registerForContextMenu(this.recyclerView)
disclaimerContainer.isVisible = Preferences.shouldShowDisclaimer(requireContext())
disclaimerDismiss.setOnClickListener {
@ -272,7 +303,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
/**
* Create a new cash game
*/
private fun createNewSession(isTournament: Boolean) {
private fun createNewSession(isTournament: Boolean, sessionId: String? = null, duplicate: Boolean = false) {
// val sessionCount = this.feedSessionAdapter.realmResults.size
// if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG
@ -287,7 +318,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
return
}
SessionActivity.newInstanceforResult(this, isTournament, requestCode = RequestCode.NEW_SESSION.value)
SessionActivity.newInstanceforResult(this, isTournament, sessionId = sessionId, duplicate = duplicate, requestCode = RequestCode.NEW_SESSION.value)
newSessionCreated = true
}

@ -61,14 +61,28 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate {
/**
* Set fragment data
*/
fun setData(isTournament: Boolean, sessionId: String) {
fun setData(isTournament: Boolean, sessionId: String? = null, duplicate: Boolean) {
val realm = getRealm()
val sessionRealm = realm.findById<Session>(sessionId)
if (sessionRealm != null) {
currentSession = sessionRealm
sessionHasBeenCustomized = true
} else {
if (sessionId != null) {
val sessionRealm = realm.findById<Session>(sessionId)
if (sessionRealm != null) {
if (duplicate) { // duplicate session
realm.executeTransaction {
val session = sessionRealm.duplicate()
currentSession = session
}
sessionHasBeenCustomized = false
} else { // show existing session
currentSession = sessionRealm
sessionHasBeenCustomized = true
}
} else {
throw PAIllegalStateException("Session cannot be null here, session id = $sessionId")
}
} else { // create new session
realm.executeTransaction { executeRealm ->
currentSession = Session.newInstance(executeRealm, isTournament)
FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, null, requireContext())

@ -0,0 +1,38 @@
package net.pokeranalytics.android.ui.view
import android.content.Context
import android.util.AttributeSet
import android.view.ContextMenu
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import timber.log.Timber
class ContextMenuRecyclerView : RecyclerView {
constructor(context: Context, attributeSet: AttributeSet?, defStyle: Int) : super(context, attributeSet, defStyle)
constructor(context: Context, attributeSet: AttributeSet?) : super(context, attributeSet)
constructor(context: Context) : super(context)
private var mContextMenuInfo: RecyclerViewContextMenuInfo? = null
override fun getContextMenuInfo(): ContextMenu.ContextMenuInfo? {
return mContextMenuInfo
}
override fun showContextMenuForChild(originalView: View): Boolean {
val longPressPosition = getChildAdapterPosition(originalView)
Timber.d("longPressPosition = $longPressPosition")
if (longPressPosition >= 0) {
val longPressId = adapter!!.getItemId(longPressPosition)
Timber.d("longPressId = $longPressId")
mContextMenuInfo = RecyclerViewContextMenuInfo(longPressPosition, longPressId)
return super.showContextMenuForChild(originalView)
}
return false
}
class RecyclerViewContextMenuInfo(val position: Int, val id: Long) : ContextMenu.ContextMenuInfo
}

@ -57,7 +57,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appBar" />
<androidx.recyclerview.widget.RecyclerView
<net.pokeranalytics.android.ui.view.ContextMenuRecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
@ -122,6 +122,7 @@
android:layout_marginBottom="8dp"
android:text="@string/disclaimer"
android:textSize="18sp"
android:textColor="@color/white"
tools:visibility="visible" />
<com.google.android.material.button.MaterialButton

@ -17,6 +17,7 @@
android:gravity="center"
android:lines="1"
android:maxLines="1"
style="@style/PokerAnalyticsTheme.TextView.RowTitle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

@ -176,11 +176,12 @@
android:text="@string/running_session_state"
android:textAllCaps="true"
android:textSize="10sp"
android:textColor="@color/white"
android:visibility="gone" />
</LinearLayout>
<ImageView
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/nextArrow"
android:layout_width="24dp"
android:layout_height="24dp"

@ -21,7 +21,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:textSize="16sp"
style="@style/PokerAnalyticsTheme.TextView.RowTitle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/guidelineEnd"
app:layout_constraintStart_toStartOf="@+id/guidelineStart"

@ -14,7 +14,7 @@
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:textSize="16sp"
style="@style/PokerAnalyticsTheme.TextView.RowTitle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/nextArrow"
app:layout_constraintStart_toStartOf="@+id/guidelineStart"

@ -13,7 +13,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:textSize="16sp"
style="@style/PokerAnalyticsTheme.TextView.RowTitle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/guidelineEnd"
app:layout_constraintStart_toStartOf="@+id/guidelineStart"

@ -25,7 +25,7 @@
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:textSize="16sp"
style="@style/PokerAnalyticsTheme.TextView.RowTitle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/nextArrow"
app:layout_constraintStart_toEndOf="@+id/icon"

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/duplicate" android:title="@string/duplicate" android:icon="@drawable/picto_gear" app:showAsAction="always|withText" />
</menu>

@ -17,7 +17,7 @@
<item name="toolbarStyle">@style/PokerAnalyticsTheme.Toolbar</item>
<item name="bottomAppBarStyle">@style/PokerAnalyticsTheme.BottomAppBar</item>
<item name="editTextStyle">@style/PokerAnalyticsTheme.EditText</item>
<item name="android:textViewStyle">@style/PokerAnalyticsTheme.TextView</item>
<!--<item name="android:textViewStyle">@style/PokerAnalyticsTheme.TextView</item>-->
<item name="alertDialogTheme">@style/PokerAnalyticsTheme.AlertDialog</item>
<item name="chipStyle">@style/PokerAnalyticsTheme.Chip</item>
<item name="tabStyle">@style/PokerAnalyticsTheme.TabLayout</item>
@ -83,6 +83,11 @@
<item name="android:fontFamily">@font/roboto</item>
</style>
<style name="PokerAnalyticsTheme.TextView.MenuTextView">
<item name="android:textColor">@color/blue</item>
<item name="android:fontFamily">@font/roboto</item>
</style>
<style name="PokerAnalyticsTheme.TextView.Title">
<item name="android:textSize">22sp</item>
<item name="android:textColor">@color/white</item>

Loading…
Cancel
Save