Fixes + calendar badge

powerreport
Laurent 3 years ago
parent f5115e53e4
commit 89effc942f
  1. 8
      app/src/main/java/net/pokeranalytics/android/calculus/ReportWhistleBlower.kt
  2. 79
      app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt
  3. 43
      app/src/main/java/net/pokeranalytics/android/ui/adapter/HomePagerAdapter.kt
  4. 10
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt
  5. 9
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
  6. 10
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/BaseFragment.kt
  7. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/feed/FeedFragment.kt
  8. 6
      app/src/main/java/net/pokeranalytics/android/ui/view/rows/SettingsRow.kt
  9. 3
      app/src/main/java/net/pokeranalytics/android/ui/view/rows/StaticReport.kt
  10. 48
      app/src/main/java/net/pokeranalytics/android/util/Preferences.kt
  11. 26
      app/src/main/java/net/pokeranalytics/android/util/SingletonHolder.kt
  12. 5
      app/src/main/res/layout/row_title_badge_value.xml
  13. 1
      app/src/main/res/values/strings.xml

@ -93,6 +93,10 @@ class ReportWhistleBlower(var context: Context) {
}
}
fun clearNotifications() {
this.currentNotifications.clear()
}
}
class ReportTask(private var whistleBlower: ReportWhistleBlower, var context: Context) {
@ -100,7 +104,7 @@ class ReportTask(private var whistleBlower: ReportWhistleBlower, var context: Co
private var cancelled = false
private val coroutineContext: CoroutineContext
get() = Dispatchers.Main
get() = Dispatchers.Default
fun start() {
launchReports()
@ -233,7 +237,7 @@ class ReportTask(private var whistleBlower: ReportWhistleBlower, var context: Co
private fun analyseOptimalDuration(realm: Realm, staticReport: StaticReport, key: PerformanceKey, duration: Double) {
var storePerf: Boolean = true
var storePerf = true
val performance = realm.where(Performance::class.java)
.equalTo("reportId", staticReport.uniqueIdentifier)

@ -11,11 +11,25 @@ import net.pokeranalytics.android.BuildConfig
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.NewPerformanceListener
import net.pokeranalytics.android.databinding.ActivityHomeBinding
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.Currency
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.adapter.HomePagerAdapter
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.billing.AppGuard
import net.pokeranalytics.android.util.extensions.findAll
import net.pokeranalytics.android.util.extensions.isSameMonth
import java.util.*
enum class Tab(var identifier: Int) {
HISTORY(0),
STATS(1),
CALENDAR(2),
REPORTS(3),
SETTINGS(4)
}
class HomeActivity : BaseActivity(), NewPerformanceListener {
@ -31,21 +45,26 @@ class HomeActivity : BaseActivity(), NewPerformanceListener {
private var homePagerAdapter: HomePagerAdapter? = null
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
if (binding.viewPager.currentItem == Tab.REPORTS.identifier) {
this.paApplication.reportWhistleBlower?.clearNotifications()
}
when (item.itemId) {
R.id.navigation_history -> {
displayFragment(0)
displayFragment(Tab.HISTORY)
}
R.id.navigation_stats -> {
displayFragment(1)
displayFragment(Tab.STATS)
}
R.id.navigation_calendar -> {
displayFragment(2)
displayFragment(Tab.CALENDAR)
}
R.id.navigation_reports -> {
displayFragment(3)
displayFragment(Tab.REPORTS)
}
R.id.navigation_settings -> {
displayFragment(4)
displayFragment(Tab.SETTINGS)
}
}
binding.navigation.getOrCreateBadge(item.itemId).isVisible = false
@ -56,6 +75,7 @@ class HomeActivity : BaseActivity(), NewPerformanceListener {
super.onResume()
AppGuard.requestPurchasesUpdate()
this.homePagerAdapter?.activityResumed()
lookForCalendarBadge()
}
private lateinit var binding: ActivityHomeBinding
@ -132,13 +152,52 @@ class HomeActivity : BaseActivity(), NewPerformanceListener {
/**
* Display a new fragment
*/
private fun displayFragment(index: Int) {
binding.viewPager.setCurrentItem(index, false)
private fun displayFragment(tab: Tab) {
binding.viewPager.setCurrentItem(tab.identifier, false)
this.homePagerAdapter?.tabSelected(tab)
}
override fun newBestPerformanceHandler() {
binding.navigation.getOrCreateBadge(R.id.navigation_reports).isVisible = true
binding.navigation.getOrCreateBadge(R.id.navigation_reports).number = 1
if (Preferences.showInAppBadges(this)) {
binding.navigation.getOrCreateBadge(R.id.navigation_reports).isVisible = true
binding.navigation.getOrCreateBadge(R.id.navigation_reports).number = 1
}
}
private fun lookForCalendarBadge() {
if (!Preferences.showInAppBadges(this)) {
return
}
val date = Preferences.lastCalendarBadgeDate(this)
val cal = Calendar.getInstance()
val lastCheck = Calendar.getInstance().apply { timeInMillis = date }
if (!cal.isSameMonth(lastCheck)) {
lookForSessionsLastMonth()
}
}
private fun lookForSessionsLastMonth() {
val cal = Calendar.getInstance()
cal.add(Calendar.MONTH, -1)
val month = QueryCondition.AnyMonthOfYear(cal.get(Calendar.MONTH))
val year = QueryCondition.AnyYear(cal.get(Calendar.YEAR))
val query = Query(month, year)
val sessions = getRealm().findAll<Session>(query)
if (sessions.isNotEmpty()) {
binding.navigation.getOrCreateBadge(R.id.navigation_calendar).isVisible = true
binding.navigation.getOrCreateBadge(R.id.navigation_calendar).number = 1
Preferences.setLastCalendarBadgeDate(this, Date().time)
}
}
}

@ -2,9 +2,12 @@ package net.pokeranalytics.android.ui.adapter
import android.util.SparseArray
import android.view.ViewGroup
import androidx.core.util.forEach
import androidx.core.util.size
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.ui.activity.Tab
import net.pokeranalytics.android.ui.fragment.ReportsFragment
import net.pokeranalytics.android.ui.fragment.SettingsFragment
import net.pokeranalytics.android.ui.fragment.StatisticsFragment
@ -17,23 +20,23 @@ import java.lang.ref.WeakReference
* Home Adapter
*/
class HomePagerAdapter(fragmentManager: FragmentManager) :
FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
private var weakReferences = SparseArray<WeakReference<BaseFragment>>()
override fun getItem(position: Int): BaseFragment {
return when (position) {
0 -> FeedFragment.newInstance()
1 -> StatisticsFragment.newInstance()
2 -> CalendarFragment.newInstance()
3 -> ReportsFragment.newInstance()
4 -> SettingsFragment.newInstance()
Tab.HISTORY.identifier -> FeedFragment.newInstance()
Tab.STATS.identifier -> StatisticsFragment.newInstance()
Tab.CALENDAR.identifier -> CalendarFragment.newInstance()
Tab.REPORTS.identifier -> ReportsFragment.newInstance()
Tab.SETTINGS.identifier -> SettingsFragment.newInstance()
else -> throw PAIllegalStateException("Should not happen, position = $position")
}
}
override fun getCount(): Int {
return 5
return Tab.values().size
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
@ -49,29 +52,27 @@ class HomePagerAdapter(fragmentManager: FragmentManager) :
override fun getItemPosition(obj: Any): Int {
return when (obj) {
is FeedFragment -> 0
is StatisticsFragment -> 1
is CalendarFragment -> 2
is ReportsFragment -> 3
is SettingsFragment -> 4
is FeedFragment -> Tab.HISTORY.identifier
is StatisticsFragment -> Tab.STATS.identifier
is CalendarFragment -> Tab.CALENDAR.identifier
is ReportsFragment -> Tab.REPORTS.identifier
is SettingsFragment -> Tab.SETTINGS.identifier
else -> throw PAIllegalStateException("Should not happen for object $obj")
}
}
fun activityResumed() {
if (this.weakReferences.size() >= 4) {
this.weakReferences.forEach { _, value ->
value.get()?.activityResumed()
}
val ref = this.weakReferences.get(0)
ref?.get()?.let {
(it as FeedFragment).activityResumed()
}
}
this.weakReferences.get(4)?.get()?.let {
(it as SettingsFragment).activityResumed()
}
fun tabSelected(tab: Tab) {
if (this.weakReferences.size >= 5) {
this.weakReferences.get(tab.identifier).get()?.selectedTab()
}
}
}

@ -39,6 +39,7 @@ import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rows.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rows.StaticReport
import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.Preferences
import timber.log.Timber
import java.util.*
@ -128,6 +129,11 @@ class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSourc
}
override fun selectedTab() {
this.updateRows()
this.dataListAdapter.notifyDataSetChanged()
}
// Business
/**
@ -200,7 +206,9 @@ class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSourc
for (performance in performances) {
val report = performance.toStaticReport(getRealm())
val badge = this.paApplication?.reportWhistleBlower?.has(performance.id) ?: false
val badge = Preferences.showInAppBadges(requireContext())
&& (this.paApplication?.reportWhistleBlower?.has(performance.id) ?: false)
val reportRow = PerformanceRow(performance, report, badge)
sections.firstOrNull { it.report == report }?.let { section ->

@ -130,8 +130,8 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
}
fun activityResumed() {
this.settingsAdapterRow.notifyDataSetChanged() // refreshes session durations
override fun activityResumed() {
this.settingsAdapterRow.notifyDataSetChanged()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -184,6 +184,7 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
return when (row) {
SettingsRow.STOP_NOTIFICATION -> Preferences.showStopNotifications(requireContext())
SettingsRow.SHOULD_SHOW_BLOG_TIPS -> Preferences.shouldShowBlogTips(requireContext())
SettingsRow.SHOW_INAPP_BADGES -> Preferences.showInAppBadges(requireContext())
else -> false
}
}
@ -260,6 +261,10 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
val show = value as Boolean
Preferences.showBlogTips(show, requireContext())
}
SettingsRow.SHOW_INAPP_BADGES -> {
val show = value as Boolean
Preferences.setShowInAppBadges(requireContext(), show)
}
else -> {}
}
}

@ -70,6 +70,16 @@ abstract class BaseFragment : Fragment() {
*/
open fun onBackPressed() {}
/**
* Method called when the HomeActivity has resumed, spread to tabs only
*/
open fun activityResumed() {}
/**
* Method called when a HomeActivity tab has been selected
*/
open fun selectedTab() {}
// /**
// * Ask for app permission
// */

@ -568,7 +568,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
}
}
fun activityResumed() {
override fun activityResumed() {
this.sessionAdapter.notifyDataSetChanged() // refreshes session durations
}

@ -36,6 +36,7 @@ enum class SettingsRow : RowRepresentable {
LANGUAGE,
CURRENCY,
DEALT_HANDS_PER_HOUR,
SHOW_INAPP_BADGES,
// Export
EXPORT_CSV_SESSIONS,
@ -79,7 +80,7 @@ enum class SettingsRow : RowRepresentable {
rows.addAll(arrayListOf(FOLLOW_US, DISCORD, BLOG_TIPS, SHOULD_SHOW_BLOG_TIPS))
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.preferences))
rows.addAll(arrayListOf(CURRENCY, DEALT_HANDS_PER_HOUR))
rows.addAll(arrayListOf(CURRENCY, DEALT_HANDS_PER_HOUR, SHOW_INAPP_BADGES))
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.export))
rows.addAll(arrayListOf(EXPORT_CSV_SESSIONS, EXPORT_CSV_TRANSACTIONS))
@ -129,6 +130,7 @@ enum class SettingsRow : RowRepresentable {
POKER_RUMBLE -> R.string.poker_rumble
DISCORD -> R.string.join_discord
DEALT_HANDS_PER_HOUR -> R.string.dealt_hands_per_hour
SHOW_INAPP_BADGES -> R.string.show_inapp_badges
else -> null
}
}
@ -141,7 +143,7 @@ enum class SettingsRow : RowRepresentable {
VERSION, SUBSCRIPTION -> RowViewType.TITLE_VALUE.ordinal
LANGUAGE, CURRENCY -> RowViewType.TITLE_VALUE_ARROW.ordinal
FOLLOW_US -> RowViewType.ROW_FOLLOW_US.ordinal
STOP_NOTIFICATION, SHOULD_SHOW_BLOG_TIPS -> RowViewType.TITLE_SWITCH.ordinal
STOP_NOTIFICATION, SHOULD_SHOW_BLOG_TIPS, SHOW_INAPP_BADGES -> RowViewType.TITLE_SWITCH.ordinal
STOP_NOTIFICATION_MESSAGE -> RowViewType.INFO.ordinal
else -> RowViewType.TITLE_ARROW.ordinal
}

@ -56,7 +56,8 @@ sealed class StaticReport(override var uniqueIdentifier: Int) : RowRepresentable
}
val basicReports: Set<StaticReport> = setOf(General)
val basicReports: Set<StaticReport> = setOf(General, Blinds, TournamentBuyin,
DayOfWeek, Location, TournamentType, Game, TableSize, Duration, OptimalDuration)
}

@ -45,7 +45,9 @@ class Preferences {
LAST_REVIEW_REQUEST_DATE("lastReviewRequestDate"),
PATCH_NEGATIVE_LIMITS("negativeLimits"),
PATCH_STAKES("patchStakes"),
CLEAN_BLINDS_FILTERS("deleteBlindsFilters")
CLEAN_BLINDS_FILTERS("deleteBlindsFilters"),
SHOW_INAPP_BADGES("showInAppBadges"),
LAST_CALENDAR_BADGE_DATE("lastCalendarBadgeDate")
}
enum class FeedMessage {
@ -302,7 +304,24 @@ class Preferences {
fun getFirstLaunchDate(context: Context): Long {
return getLong(Keys.FIRST_LAUNCH, context)
}
}
fun showInAppBadges(context: Context): Boolean {
return getBoolean(Keys.SHOW_INAPP_BADGES, context, true)
}
fun setShowInAppBadges(context: Context, show: Boolean) {
setBoolean(Keys.SHOW_INAPP_BADGES, show, context)
}
fun lastCalendarBadgeDate(context: Context): Long {
return getLong(Keys.LAST_CALENDAR_BADGE_DATE, context)
}
fun setLastCalendarBadgeDate(context: Context, date: Long) {
setLong(Keys.LAST_CALENDAR_BADGE_DATE, date, context)
}
}
}
@ -349,28 +368,3 @@ class UserDefaults private constructor(context: Context) {
}
}
open class SingletonHolder<out T, in A>(creator: (A) -> T) {
private var creator: ((A) -> T)? = creator
@Volatile
private var instance: T? = null
fun init(context: A): T {
val i = instance
if (i != null) {
return i
}
return synchronized(this) {
val i2 = instance
if (i2 != null) {
i2
} else {
val created = creator!!(context)
instance = created
creator = null
created
}
}
}
}

@ -0,0 +1,26 @@
package net.pokeranalytics.android.util
open class SingletonHolder<out T, in A>(creator: (A) -> T) {
private var creator: ((A) -> T)? = creator
@Volatile
private var instance: T? = null
fun init(context: A): T {
val i = instance
if (i != null) {
return i
}
return synchronized(this) {
val i2 = instance
if (i2 != null) {
i2
} else {
val created = creator!!(context)
instance = created
creator = null
created
}
}
}
}

@ -9,10 +9,11 @@
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/title"
style="@style/PokerAnalyticsTheme.TextView.RowTitle"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:ellipsize="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/guidelineStart"
app:layout_constraintTop_toTopOf="parent"
@ -32,7 +33,7 @@
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/value"
style="@style/PokerAnalyticsTheme.TextView.RowValue"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:ellipsize="end"

@ -825,5 +825,6 @@
<string name="transfer">Transfer</string>
<string name="destination">Destination</string>
<string name="optimal_duration">Optimal duration</string>
<string name="show_inapp_badges">Show in-app badges</string>
</resources>

Loading…
Cancel
Save