diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt index 849487ec..be7eed13 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FeedSessionRowRepresentableAdapter.kt @@ -77,14 +77,13 @@ class FeedSessionRowRepresentableAdapter( val layout = LayoutInflater.from(parent.context).inflate(net.pokeranalytics.android.R.layout.row_header_title, parent, false) HeaderTitleViewHolder(layout) } - } override fun getItemViewType(position: Int): Int { - if (sortedHeaders.containsKey(position)) { - return RowViewType.HEADER_TITLE.ordinal + return if (sortedHeaders.containsKey(position)) { + RowViewType.HEADER_TITLE.ordinal } else { - return RowViewType.ROW_SESSION.ordinal + RowViewType.ROW_SESSION.ordinal } } @@ -187,8 +186,6 @@ class FeedSessionRowRepresentableAdapter( */ 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/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index dc1608ad..a23922e8 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -191,15 +191,22 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { registerForContextMenu(this.recyclerView) - disclaimerContainer.isVisible = Preferences.shouldShowDisclaimer(requireContext()) + val messageToShow: Preferences.FeedMessage? = Preferences.feedMessageToShow(requireContext()) - disclaimerDismiss.setOnClickListener { - Preferences.setStopShowingDisclaimer(requireContext()) + if (messageToShow != null) { + messageBox.isVisible = true + message.text = getString(messageToShow.resId) - disclaimerContainer.animate().translationY(disclaimerContainer.height.toFloat()) - .setInterpolator(FastOutSlowInInterpolator()) - .withEndAction { disclaimerContainer?.isVisible = false } - .start() + messageBoxDismiss.setOnClickListener { + Preferences.setStopShowingMessage(messageToShow, requireContext()) + + messageBox.animate().translationY(messageBox.height.toFloat()) + .setInterpolator(FastOutSlowInInterpolator()) + .withEndAction { messageBox?.isVisible = false } + .start() + } + } else { + messageBox.isVisible = false } addButton.setOnClickListener { diff --git a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt index beff0335..8c72fef1 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt @@ -2,6 +2,10 @@ package net.pokeranalytics.android.util import android.content.Context import android.preference.PreferenceManager +import io.realm.Realm +import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.util.extensions.count import java.util.* class Preferences { @@ -19,172 +23,207 @@ class Preferences { } } - enum class Keys(override var identifier: String) : PreferenceKey { - CURRENCY_CODE("CurrencyCode"), - LOCALE_CODE("LocaleCode"), - FIRST_LAUNCH("firstLaunch"), - STOP_SHOWING_DISCLAIMER("stopShowingDisclaimer"), - ACTIVE_FILTER_ID("ActiveFilterId"), - LATEST_PURCHASE("latestPurchase"), - PATCH_BREAK("patchBreaks"), - PATCH_TRANSACTION_TYPES_NAMES("patchTransactionTypesNames"), - PATCH_BLINDS_FORMAT("patchBlindFormat") - } - - companion object { - - fun setString(key: PreferenceKey, value: String, context: Context) { - val preferences = PreferenceManager.getDefaultSharedPreferences(context) - val editor = preferences.edit() - editor.putString(key.identifier, value) - editor.apply() - } - - private fun removeKey(key: Keys, context: Context) { - val preferences = PreferenceManager.getDefaultSharedPreferences(context) - val editor = preferences.edit() - editor.remove(key.identifier) - editor.apply() - } - - fun getString(key: Keys, context: Context) : String? { - val preferences = PreferenceManager.getDefaultSharedPreferences(context) - return preferences.getString(key.identifier, null) - } - - fun setBoolean(key: PreferenceKey, value: Boolean, context: Context) { - val preferences = PreferenceManager.getDefaultSharedPreferences(context) - val editor = preferences.edit() - editor.putBoolean(key.identifier, value) - editor.apply() - } - - fun getBoolean(key: PreferenceKey, context: Context, defaultValue: Boolean? = false) : Boolean { - val preferences = PreferenceManager.getDefaultSharedPreferences(context) - return preferences.getBoolean(key.identifier, defaultValue ?: false) - } - - fun setCurrencyCode(currencyCode: String, context: Context) { - setString(Keys.CURRENCY_CODE, currencyCode, context) - UserDefaults.setCurrencyValues(context) - } - - fun setActiveFilterId(filterId: String, context: Context) { - setString(Keys.ACTIVE_FILTER_ID, filterId, context) - } - - fun getActiveFilterId(context: Context) : String? { - return getString(Keys.ACTIVE_FILTER_ID, context) - } - - fun removeActiveFilterId(context: Context) { - removeKey(Keys.ACTIVE_FILTER_ID, context) - } - - private fun getCurrencyCode(context: Context) : String? { - return getString(Keys.CURRENCY_CODE, context) - } - - fun getCurrencyLocale(context : Context) : Locale? { - getCurrencyCode(context)?.let { currencyCode -> - UserDefaults.availableCurrencyLocales.filter { - Currency.getInstance(it).currencyCode == currencyCode - }.firstOrNull()?.let { - return it - } - } - return null - } - - fun getDefaultCurrency(context: Context) : Currency? { - getCurrencyLocale(context)?.let { - return Currency.getInstance(it) - } - return null - } - - fun setStopShowingDisclaimer(context: Context) { - setBoolean(Keys.STOP_SHOWING_DISCLAIMER, true, context) - } - - fun shouldShowDisclaimer(context: Context) : Boolean { - return !getBoolean(Keys.STOP_SHOWING_DISCLAIMER, context) - } - - fun executeOnce(key: Keys, context: Context, executable: () -> Unit) { - if (!getBoolean(key, context)) { - executable.invoke() - setBoolean(key, true, context) - } - } - - } + enum class Keys(override var identifier: String) : PreferenceKey { + CURRENCY_CODE("CurrencyCode"), + LOCALE_CODE("LocaleCode"), + FIRST_LAUNCH("firstLaunch"), + STOP_SHOWING_DISCLAIMER("stopShowingDisclaimer"), + STOP_SHOWING_DUPLICATE("stopShowingDuplicate"), + ACTIVE_FILTER_ID("ActiveFilterId"), + LATEST_PURCHASE("latestPurchase"), + PATCH_BREAK("patchBreaks"), + PATCH_TRANSACTION_TYPES_NAMES("patchTransactionTypesNames"), + PATCH_BLINDS_FORMAT("patchBlindFormat") + } + + enum class FeedMessage { + DISCLAIMER, + DUPLICATE; + + val resId: Int + get() { + return when (this) { + DISCLAIMER -> R.string.disclaimer + DUPLICATE -> R.string.longtap_to_duplicate + } + } + + val key: Keys + get() { + return when (this) { + DISCLAIMER -> Keys.STOP_SHOWING_DISCLAIMER + DUPLICATE -> Keys.STOP_SHOWING_DUPLICATE + } + } + + } + + companion object { + + fun setString(key: PreferenceKey, value: String, context: Context) { + val preferences = PreferenceManager.getDefaultSharedPreferences(context) + val editor = preferences.edit() + editor.putString(key.identifier, value) + editor.apply() + } + + private fun removeKey(key: Keys, context: Context) { + val preferences = PreferenceManager.getDefaultSharedPreferences(context) + val editor = preferences.edit() + editor.remove(key.identifier) + editor.apply() + } + + fun getString(key: Keys, context: Context): String? { + val preferences = PreferenceManager.getDefaultSharedPreferences(context) + return preferences.getString(key.identifier, null) + } + + fun setBoolean(key: PreferenceKey, value: Boolean, context: Context) { + val preferences = PreferenceManager.getDefaultSharedPreferences(context) + val editor = preferences.edit() + editor.putBoolean(key.identifier, value) + editor.apply() + } + + fun getBoolean(key: PreferenceKey, context: Context, defaultValue: Boolean? = false): Boolean { + val preferences = PreferenceManager.getDefaultSharedPreferences(context) + return preferences.getBoolean(key.identifier, defaultValue ?: false) + } + + fun setCurrencyCode(currencyCode: String, context: Context) { + setString(Keys.CURRENCY_CODE, currencyCode, context) + UserDefaults.setCurrencyValues(context) + } + + fun setActiveFilterId(filterId: String, context: Context) { + setString(Keys.ACTIVE_FILTER_ID, filterId, context) + } + + fun getActiveFilterId(context: Context): String? { + return getString(Keys.ACTIVE_FILTER_ID, context) + } + + fun removeActiveFilterId(context: Context) { + removeKey(Keys.ACTIVE_FILTER_ID, context) + } + + private fun getCurrencyCode(context: Context): String? { + return getString(Keys.CURRENCY_CODE, context) + } + + fun getCurrencyLocale(context: Context): Locale? { + getCurrencyCode(context)?.let { currencyCode -> + UserDefaults.availableCurrencyLocales.filter { + Currency.getInstance(it).currencyCode == currencyCode + }.firstOrNull()?.let { + return it + } + } + return null + } + + fun getDefaultCurrency(context: Context): Currency? { + getCurrencyLocale(context)?.let { + return Currency.getInstance(it) + } + return null + } + + fun setStopShowingMessage(message: FeedMessage, context: Context) { + setBoolean(message.key,true, context) + } + + fun feedMessageToShow(context: Context): FeedMessage? { + + if (!getBoolean(Keys.STOP_SHOWING_DISCLAIMER, context)) { + return FeedMessage.DISCLAIMER + } + + val realm = Realm.getDefaultInstance() + val sessionCount = realm.count(Session::class.java) + realm.close() + if (sessionCount in 2..10 && !getBoolean(Keys.STOP_SHOWING_DUPLICATE, context)) { + return FeedMessage.DUPLICATE + } + return null + } + + fun executeOnce(key: Keys, context: Context, executable: () -> Unit) { + if (!getBoolean(key, context)) { + executable.invoke() + setBoolean(key, true, context) + } + } + + } } class UserDefaults private constructor(context: Context) { - init { - setCurrencyValues(context) - } - - companion object : SingletonHolder(::UserDefaults) { - lateinit var currency : Currency - - fun setCurrencyValues(context: Context) { - currency = Preferences.getDefaultCurrency(context) ?: getLocaleCurrency() - } - - val availableCurrencyLocales = Locale.getAvailableLocales().mapNotNull { - try { - Currency.getInstance(it) - it - } catch (e: Exception) { - null - } - } - - /** - * Return the locale currency, or en_US if there - */ - fun getLocaleCurrency() : Currency { - return try { - Currency.getInstance(Locale.getDefault()) - } catch (ex: Exception) { - when (Locale.getDefault().language) { - "en" -> Currency.getInstance(Locale("en", "US")) - "fr" -> Currency.getInstance(Locale("fr", "FR")) - "es" -> Currency.getInstance(Locale("es", "ES")) - "de" -> Currency.getInstance(Locale("de", "DE")) - "ja" -> Currency.getInstance(Locale("ja", "JP")) - "zh" -> Currency.getInstance(Locale("zh", "CN")) - else -> Currency.getInstance(Locale("en", "US")) - } - } - } - } + init { + setCurrencyValues(context) + } + + companion object : SingletonHolder(::UserDefaults) { + lateinit var currency: Currency + + fun setCurrencyValues(context: Context) { + currency = Preferences.getDefaultCurrency(context) ?: getLocaleCurrency() + } + + val availableCurrencyLocales = Locale.getAvailableLocales().mapNotNull { + try { + Currency.getInstance(it) + it + } catch (e: Exception) { + null + } + } + + /** + * Return the locale currency, or en_US if there + */ + fun getLocaleCurrency(): Currency { + return try { + Currency.getInstance(Locale.getDefault()) + } catch (ex: Exception) { + when (Locale.getDefault().language) { + "en" -> Currency.getInstance(Locale("en", "US")) + "fr" -> Currency.getInstance(Locale("fr", "FR")) + "es" -> Currency.getInstance(Locale("es", "ES")) + "de" -> Currency.getInstance(Locale("de", "DE")) + "ja" -> Currency.getInstance(Locale("ja", "JP")) + "zh" -> Currency.getInstance(Locale("zh", "CN")) + else -> Currency.getInstance(Locale("en", "US")) + } + } + } + } } open class SingletonHolder(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 - } - } - } + 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 + } + } + } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_feed.xml b/app/src/main/res/layout/fragment_feed.xml index b8000803..37e78201 100644 --- a/app/src/main/res/layout/fragment_feed.xml +++ b/app/src/main/res/layout/fragment_feed.xml @@ -103,7 +103,7 @@ app:layout_constraintEnd_toEndOf="parent" /> Noms de tournoi Propriétés de tournoi En attente - Poker Analytics est un tracker de sessions. Il s\'agit pour l\'instant d\'une version allégée de la version iOS existante. Nous allons ajouter les fonctionnalités au fur et à mesure. L\'app fonctionnera avec un abonnement illimité de 29,99€ par an, mais nous la proposons gratuitement en attendant plus de fonctionnalités + Poker Analytics est un tracker de sessions. L\'app fonctionne avec un abonnement illimité annuel, mais vous disposez de 10 sessions + un essai limité dans le temps pour la tester. C\'est compris ! La propriété doit avoir un nom Une propriété utilise déjà ce nom diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4b50e2a5..e10b1f06 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -50,7 +50,7 @@ Tournament feature Tournament features Pending - Poker Analytics is a poker tracking app. We’re currently on our way to reproduce the iOS app and you’re currently using a lighter version. The app will work with a US$29.99 yearly subscription for an unlimited usage, but will be free until reaching the appropriate feature coverage. + Poker Analytics is a poker tracking app.\nThe app works with a yearly subscription for an unlimited usage, but you get 10 sessions + a free trial to test the app. I understand You need to give a name to this tournament feature A tournament feature with the same name already exists. @@ -660,7 +660,7 @@ Subscription terms of use:\n• Payment will be charged to iTunes Account at confirmation of purchase\n• Subscription automatically renews unless auto-renew is turned off at least 24-hours before the end of the current period\n• Account will be charged for renewal within 24-hours prior to the end of the current period, and identify the cost of the renewal\n• Subscriptions may be managed by the user and auto-renewal may be turned off by going to the user\'s Account Settings after purchase\n• Any unused portion of a free trial period, if offered, will be forfeited when the user purchases a subscription to that publication, where applicable Privacy policy We\'re truly sorry, but something is wrong here…You may be waiting for iCloud sync. Please wait and retry later. Would you mind sending us a report explaining your current state to help us solve this issue? - Tap and hold on a session to duplicate it. + Tap and hold on a session to duplicate it! Change statistic Compare Gross Amount