Adds confirmation popup when hand uses wildcards + fixes bug in ffmpeg export by adding option

blinds
Laurent 5 years ago
parent 4a43d2fac3
commit 2a49f831ea
  1. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt
  2. 36
      app/src/main/java/net/pokeranalytics/android/ui/extensions/UIExtensions.kt
  3. 38
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryActivity.kt
  4. 8
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayExportService.kt
  5. 13
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerAnimator.kt
  6. 20
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt
  7. 3
      app/src/main/res/values/strings.xml

@ -28,6 +28,7 @@ import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.util.extensions.addLineReturn
import net.pokeranalytics.android.util.extensions.formatted
import net.pokeranalytics.android.util.extensions.fullDate
import timber.log.Timber
import java.util.*
import kotlin.math.max
@ -504,6 +505,8 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable,
this.winnerPots.clear()
this.winnerPots.addAll(wonPots)
Timber.d("Pot won: ${this.winnerPots.size} for positions: ${this.winnerPots.map {it.position}} ")
}
/***

@ -3,6 +3,7 @@ package net.pokeranalytics.android.ui.extensions
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.res.Resources
import android.graphics.Bitmap
@ -106,6 +107,41 @@ fun Context.openUrl(url: String) {
ContextCompat.startActivity(this, browserIntent, null)
}
// Open custom tab
fun Context.areYouSure(title: Int? = null, message: Int? = null, positiveTitle: Int? = null, proceed: () -> Unit) {
val builder: android.app.AlertDialog.Builder = android.app.AlertDialog.Builder(this)
val messageResource = message ?: R.string.are_you_sure_you_want_to_do_this
builder.setMessage(messageResource)
title?.let { builder.setTitle(it) }
val positiveButtonTitle = positiveTitle ?: R.string.yes
builder.setPositiveButton(positiveButtonTitle) { _, _ ->
proceed()
}
builder.setNegativeButton(R.string.cancel) { _, _ ->
// nothing
}
// builder.setItems(
// arrayOf<CharSequence>(
// getString(R.string.yes),
// getString(R.string.cancel)
// )
// ) { _, index ->
// // The 'which' argument contains the index position
// // of the selected item
// when (index) {
// 0 -> proceed()
// 1 -> {} // nothing
// }
// }
builder.create().show()
}
// Display Alert Dialog
fun Activity.showAlertDialog(title: Int? = null, message: Int? = null) {
showAlertDialog(this, title, message)

@ -16,6 +16,7 @@ import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.activity.components.RequestCode
import net.pokeranalytics.android.ui.extensions.areYouSure
import net.pokeranalytics.android.ui.modules.handhistory.editor.EditorFragment
import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayExportService
import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerFragment
@ -153,14 +154,25 @@ class HandHistoryActivity : BaseActivity() {
// of the selected item
when (index) {
0 -> this.textExport()
1 -> this.videoExportAskForPermission()
2 -> this.gifExportAskForPermission()
1 -> this.videoExportWildCardsCheck()
2 -> this.gifExportWildCardsCheck()
}
}
builder.create().show()
}
private fun gifExportWildCardsCheck() {
if (this.handHistory.usesWildcards) {
areYouSure(message = R.string.wildcards_warning, positiveTitle = R.string.proceed) {
gifExportAskForPermission()
}
} else {
gifExportAskForPermission()
}
}
private fun gifExportAskForPermission() {
Toast.makeText(this, R.string.video_export_started, Toast.LENGTH_LONG).show()
@ -168,12 +180,27 @@ class HandHistoryActivity : BaseActivity() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
gifExport()
} else {
askForPermission(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), RequestCode.PERMISSION_WRITE_EXTERNAL_STORAGE.value) { granted ->
askForPermission(
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
RequestCode.PERMISSION_WRITE_EXTERNAL_STORAGE.value
) { granted ->
if (granted) {
gifExport()
}
}
}
}
private fun videoExportWildCardsCheck() {
if (this.handHistory.usesWildcards) {
areYouSure(message = R.string.wildcards_warning, positiveTitle = R.string.proceed) {
videoExportAskForPermission()
}
} else {
videoExportAskForPermission()
}
}
private fun videoExportAskForPermission() {
@ -183,7 +210,10 @@ class HandHistoryActivity : BaseActivity() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
videoExport()
} else {
askForPermission(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), RequestCode.PERMISSION_WRITE_EXTERNAL_STORAGE.value) { granted ->
askForPermission(
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
RequestCode.PERMISSION_WRITE_EXTERNAL_STORAGE.value
) { granted ->
if (granted) {
videoExport()
}

@ -180,7 +180,7 @@ class ReplayExportService : Service() {
Timber.d("Assembling images for video...")
FFmpeg.executeAsync("-f concat -safe 0 -i $dpath -vb 20M -vsync vfr -s ${width}x${height} -pix_fmt yuv420p $output") { id, rc ->
FFmpeg.executeAsync("-f concat -safe 0 -i $dpath -vb 20M -vsync vfr -s ${width}x${height} -vf fps=20 -pix_fmt yuv420p $output") { id, rc ->
when (rc) {
RETURN_CODE_SUCCESS -> {
@ -378,7 +378,7 @@ class ReplayExportService : Service() {
Environment.getExternalStorageState(tmpDir)
Timber.d("Assembling images for video...")
FFmpeg.executeAsync("-f concat -safe 0 -i $dpath -vb 20M -vsync vfr -s ${width}x${height} -pix_fmt yuv420p $output") { id, rc ->
FFmpeg.executeAsync("-f concat -safe 0 -i $dpath -vb 20M -vsync vfr -s ${width}x${height} -vf fps=20 -pix_fmt yuv420p $output") { id, rc ->
if (rc == RETURN_CODE_SUCCESS) {
Timber.d("FFMPEG command execution completed successfully")
@ -388,8 +388,8 @@ class ReplayExportService : Service() {
Timber.d(String.format("Command execution failed with rc=%d and the output below.", rc))
}
// Delete descriptor and image files
tmpDir.delete()
File(dpath).delete()
// tmpDir.delete()
// File(dpath).delete()
notifyUser(output)
}

@ -56,7 +56,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
this.frameManager.add(FrameType.GATHER_ANIMATION, framesForChipsAnimation)
}
// Chip distribution animation on the Summary
if (step == Street.SUMMARY && !this.handHistory.usesWildcards) {
if (step == Street.SUMMARY) {
this.frameManager.add(FrameType.DISTRIBUTION_ANIMATION, framesForChipsAnimation)
}
this.frameManager.add(FrameType.STATE, 1)
@ -255,7 +255,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
*/
private fun setDimension(width: Float, height: Float) {
Timber.d("Setting dimensions...")
// Timber.d("Setting dimensions...")
this.width = width
this.height = height
@ -272,7 +272,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
// else -> Pair(3.7f, 4.7f)
// }
Timber.d("playerPerRow = $playerPerRow, playerPerColumn = $playerPerColumn")
// Timber.d("playerPerRow = $playerPerRow, playerPerColumn = $playerPerColumn")
// val playerPerColumn = if (portrait) grid.second else grid.first
// val playerPerRow = if (portrait) grid.first else grid.second
@ -519,6 +519,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
suspend fun generateVideoContent(context: Context): File {
var ffmpegImageDescriptor = ""
var vo = 0.0
var count = 0
var imagePath = ""
@ -535,7 +536,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
val bitmap = Bitmap.createBitmap(this.width.toInt(), this.height.toInt(), Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
val vo = this.visualOccurences / 90.0 // this is needed before the call to drawTable which pass to the next frame
vo = this.visualOccurences / 90.0 // this is needed before the call to drawTable which pass to the next frame
this.drawer.drawTable(canvas, context)
@ -550,15 +551,13 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
count++
awaitFrame()
}
nextStep()
}
Timber.d("COUNT = $count")
// from the ffmpeg doc: (Due to a quirk, the last image has to be specified twice - the 2nd time without any duration directive)
ffmpegImageDescriptor = ffmpegImageDescriptor.plus("file '$imagePath'\n")
FileUtils.writeToFile(ffmpegImageDescriptor, FFMPEG_DESCRIPTOR_FILE, directory)

@ -70,7 +70,7 @@ class TableDrawer {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
textPaint.typeface = ResourcesCompat.getFont(context, R.font.roboto_bold)
cardTextPaint.typeface = ResourcesCompat.getFont(context, R.font.roboto_bold)
cardTextPaint.typeface = ResourcesCompat.getFont(context, R.font.roboto_black)
}
}
@ -133,7 +133,7 @@ class TableDrawer {
* Draw chips
* A chip should appears when the player has put some money during the current street
*/
private fun drawPlayerChips(i: Int, canvas: Canvas, context: Context) {
private fun drawPlayerChips(position: Int, canvas: Canvas, context: Context) {
when (animator.currentStep) {
is Street -> {
@ -141,36 +141,36 @@ class TableDrawer {
FrameType.STATE -> {
if (animator.currentStep == Street.SUMMARY) {
val winnerPots = animator.handHistory.winnerPots.firstOrNull { it.position == i }
val winnerPots = animator.handHistory.winnerPots.firstOrNull { it.position == position }
winnerPots?.let { pot ->
val color = colorForAmount(pot.amount)
val circle = animator.animatedChipCircleFromPot(i)
val circle = animator.animatedChipCircleFromPot(position)
drawChipCircle(circle, color, canvas, context)
drawChipText(pot.amount, animator.chipText(i), canvas, context)
drawChipText(pot.amount, animator.chipText(position), canvas, context)
}
}
}
FrameType.GATHER_ANIMATION -> {
animator.lastCommittedAmount(i)?.let { amount ->
animator.lastCommittedAmount(position)?.let { amount ->
val color = colorForAmount(amount)
val circle = animator.animatedChipCircleToPot(i)
val circle = animator.animatedChipCircleToPot(position)
drawChipCircle(circle, color, canvas, context)
}
}
FrameType.DISTRIBUTION_ANIMATION -> {
val winnerPots = animator.handHistory.winnerPots.firstOrNull { it.position == i }
val winnerPots = animator.handHistory.winnerPots.firstOrNull { it.position == position }
winnerPots?.let { pot ->
val color = colorForAmount(pot.amount)
val circle = animator.animatedChipCircleFromPot(i)
val circle = animator.animatedChipCircleFromPot(position)
drawChipCircle(circle, color, canvas, context)
}
}
}
}
is ComputedAction -> {
drawChipForAction(i, canvas, context)
drawChipForAction(position, canvas, context)
}
}

@ -114,6 +114,7 @@
<string name="ante_value">Ante</string>
<string name="app_store">Upgrade</string>
<string name="are_you_sure_you_want_to_delete">Are you sure you want to delete?</string>
<string name="are_you_sure_you_want_to_do_this">Are you sure you want to do this?</string>
<string name="are_you_sure_you_want_to_import_your_data_from_v3">Are you sure you want to import your Poker Analytics 3 data? This will erase your current Poker Analytics 5 data.</string>
<string name="ask_user_to_add_icloud_account_to_be_able_to_use_icloud_storage">You need to add an iCloud account on your device to be able to use this feature.</string>
<string name="ask_user_to_enable_icloud_to_migrate_data_from_icloud_to_local">You need to re-enable iCloud to be able to migrate your data from iCloud and be able to turn off iCloud storage.</string>
@ -818,5 +819,7 @@
<string name="dhph_explanation">You can change the DHPH (Dealt Hands Per Hour) values here. It corresponds to the total number of hands all players receives at a table in one hour. Example: Your local 10-max game deals 25 hands per hour, enter 10 x 25 = 250.</string>
<string name="dealt_hands_per_hour">Dealt hands per hour</string>
<string name="report_name_cannot_be_empty">You need to give a name to the report</string>
<string name="wildcards_warning">The hand you\'ve created has suit wildcards. By convenience - sorry! - we\'re currently removing such cards to determine which hand wins, resulting in potentially wrong chip distribution.</string>
<string name="proceed">proceed</string>
</resources>

Loading…
Cancel
Save