Adds red dot when no email is set

realmasync
Laurent 2 years ago
parent e89b597de6
commit 6441c04bae
  1. 13
      app/src/main/java/net/pokeranalytics/android/api/BackupApi.kt
  2. 1
      app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt
  3. 15
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
  4. 7
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt
  5. 12
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/BaseFragment.kt
  6. 14
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  7. 3
      app/src/main/java/net/pokeranalytics/android/ui/view/rows/SettingsRow.kt
  8. 11
      app/src/main/java/net/pokeranalytics/android/util/BackupOperator.kt
  9. 7
      app/src/main/java/net/pokeranalytics/android/util/Preferences.kt
  10. 15
      app/src/main/java/net/pokeranalytics/android/util/extensions/ContextExtensions.kt

@ -1,8 +1,10 @@
package net.pokeranalytics.android.api package net.pokeranalytics.android.api
import android.content.Context
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import net.pokeranalytics.android.util.extensions.isNetworkAvailable
import okhttp3.MediaType import okhttp3.MediaType
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.RequestBody import okhttp3.RequestBody
@ -33,13 +35,12 @@ interface MyBackupApi {
fun postFile(@Part mail: MultipartBody.Part, @Part fileBody: MultipartBody.Part): Call<Void> fun postFile(@Part mail: MultipartBody.Part, @Part fileBody: MultipartBody.Part): Call<Void>
} }
object BackupApi { object BackupApi {
val service = BackupService() val service = BackupService()
// curl -F recipient=laurent@staxriver.com -F file=@test.txt https://www.pokeranalytics.net/backup/send // curl -F recipient=laurent@staxriver.com -F file=@test.txt https://www.pokeranalytics.net/backup/send
fun backupFile(mail: String, fileName: String, fileContent: String) { fun backupFile(context: Context, mail: String, fileName: String, fileContent: String): Boolean {
val filePart = MultipartBody.Part.createFormData( val filePart = MultipartBody.Part.createFormData(
"file", "file",
@ -49,14 +50,16 @@ object BackupApi {
val mailPart = MultipartBody.Part.createFormData("recipient", mail) val mailPart = MultipartBody.Part.createFormData("recipient", mail)
return if (context.isNetworkAvailable()) {
CoroutineScope(context = Dispatchers.IO).launch { CoroutineScope(context = Dispatchers.IO).launch {
val response = service.backupApi.postFile(mailPart, filePart).execute() val response = service.backupApi.postFile(mailPart, filePart).execute()
Timber.d("response code = ${response.code()}") Timber.d("response code = ${response.code()}")
Timber.d("success = ${response.isSuccessful}") Timber.d("success = ${response.isSuccessful}")
} }
true
} else {
false
}
} }
} }

@ -68,5 +68,4 @@ class RowRepresentableAdapter(
this.dataSource = dataSource this.dataSource = dataSource
} }
} }

@ -70,11 +70,12 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
return fragment return fragment
} }
val rowRepresentation: List<RowRepresentable> by lazy { // fun rowRepresentation(context: Context): List<RowRepresentable> {
val rows = ArrayList<RowRepresentable>() // val rows = ArrayList<RowRepresentable>()
rows.addAll(SettingsRow.getRows()) // val hasBackupEmail = Preferences.getBackupEmail(context)?.isNotBlank() ?: false
rows // rows.addAll(SettingsRow.getRows(hasBackupEmail))
} // return rows
// }
} }
@ -201,7 +202,7 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
} }
override fun adapterRows(): List<RowRepresentable> { override fun adapterRows(): List<RowRepresentable> {
return rowRepresentation return SettingsRow.getRows()
} }
override fun charSequenceForRow( override fun charSequenceForRow(
@ -223,6 +224,7 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
SettingsRow.STOP_NOTIFICATION -> Preferences.showStopNotifications(requireContext()) SettingsRow.STOP_NOTIFICATION -> Preferences.showStopNotifications(requireContext())
SettingsRow.SHOULD_SHOW_BLOG_TIPS -> Preferences.shouldShowBlogTips(requireContext()) SettingsRow.SHOULD_SHOW_BLOG_TIPS -> Preferences.shouldShowBlogTips(requireContext())
SettingsRow.SHOW_INAPP_BADGES -> Preferences.showInAppBadges(requireContext()) SettingsRow.SHOW_INAPP_BADGES -> Preferences.showInAppBadges(requireContext())
SettingsRow.BACKUP_EMAIL -> !Preferences.hasBackupEmail(requireContext())
else -> false else -> false
} }
} }
@ -298,6 +300,7 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep
context?.let { context -> context?.let { context ->
showEditTextAlertDialog(context, InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS, messageResId = R.string.backup_email_title, editTextText = Preferences.getBackupEmail(context)) { value -> showEditTextAlertDialog(context, InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS, messageResId = R.string.backup_email_title, editTextText = Preferences.getBackupEmail(context)) { value ->
Preferences.setBackupEmail(value, context) Preferences.setBackupEmail(value, context)
this.settingsAdapterRow.notifyDataSetChanged()
} }
} }
} }

@ -30,6 +30,7 @@ import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.billing.AppGuard import net.pokeranalytics.android.util.billing.AppGuard
import net.pokeranalytics.android.util.billing.IAPProducts import net.pokeranalytics.android.util.billing.IAPProducts
import net.pokeranalytics.android.util.billing.PurchaseListener import net.pokeranalytics.android.util.billing.PurchaseListener
import net.pokeranalytics.android.util.extensions.isNetworkAvailable
import timber.log.Timber import timber.log.Timber
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.time.Period import java.time.Period
@ -75,7 +76,7 @@ class SubscriptionFragment : BaseFragment(), ProductDetailsResponseListener, Pur
AppGuard.registerListener(this) AppGuard.registerListener(this)
if (!isNetworkAvailable()) { if (!requireContext().isNetworkAvailable()) {
Toast.makeText(requireContext(), R.string.connection_unavailable, Toast.LENGTH_LONG).show() Toast.makeText(requireContext(), R.string.connection_unavailable, Toast.LENGTH_LONG).show()
return return
} }
@ -158,10 +159,10 @@ class SubscriptionFragment : BaseFragment(), ProductDetailsResponseListener, Pur
purchase.isEnabled = true purchase.isEnabled = true
purchase.setOnClickListener { purchase.setOnClickListener {
val network = isNetworkAvailable() val network = requireContext().isNetworkAvailable()
Timber.d("isNetworkAvailable = $network ") Timber.d("isNetworkAvailable = $network ")
if (!isNetworkAvailable()) { if (!network) {
Toast.makeText(requireContext(), R.string.connection_unavailable, Toast.LENGTH_LONG).show() Toast.makeText(requireContext(), R.string.connection_unavailable, Toast.LENGTH_LONG).show()
return@setOnClickListener return@setOnClickListener
} }

@ -1,8 +1,5 @@
package net.pokeranalytics.android.ui.fragment.components package net.pokeranalytics.android.ui.fragment.components
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
@ -176,15 +173,6 @@ abstract class BaseFragment : Fragment() {
alternativeLabels) alternativeLabels)
} }
/***
* Returns whether the network is available or not
*/
fun isNetworkAvailable(): Boolean {
val cm = requireContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val capability = cm.getNetworkCapabilities(cm.activeNetwork)
return capability?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ?: false
}
fun showSnackBar(message: String) { fun showSnackBar(message: String) {
this.view?.let { view -> this.view?.let { view ->
val snackBar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE) val snackBar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE)

@ -702,8 +702,6 @@ enum class RowViewType(private var layoutRes: Int) : ViewIdentifier {
BindableHolder { BindableHolder {
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) { override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
if (row is PerformanceRow) {
itemView.findViewById<AppCompatTextView>(R.id.title)?.let { itemView.findViewById<AppCompatTextView>(R.id.title)?.let {
it.text = row.localizedTitle(itemView.context) it.text = row.localizedTitle(itemView.context)
} }
@ -713,6 +711,13 @@ enum class RowViewType(private var layoutRes: Int) : ViewIdentifier {
itemView.findViewById<AppCompatImageView>(R.id.badge)?.let { itemView.findViewById<AppCompatImageView>(R.id.badge)?.let {
it.isVisible = adapter.dataSource.boolForRow(row) it.isVisible = adapter.dataSource.boolForRow(row)
} }
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.setOnClickListener(listener)
if (row is PerformanceRow) {
itemView.findViewById<AppCompatImageView>(R.id.nextArrow)?.let { itemView.findViewById<AppCompatImageView>(R.id.nextArrow)?.let {
it.visibility = if (row.report.hasGraph) { it.visibility = if (row.report.hasGraph) {
View.VISIBLE View.VISIBLE
@ -720,11 +725,6 @@ enum class RowViewType(private var layoutRes: Int) : ViewIdentifier {
View.GONE View.GONE
} }
} }
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.setOnClickListener(listener)
} }
} }
} }

@ -143,7 +143,8 @@ enum class SettingsRow : RowRepresentable {
return when (this) { return when (this) {
BANKROLL_REPORT, TOP_10, PLAYERS -> RowViewType.TITLE_ICON_ARROW.ordinal BANKROLL_REPORT, TOP_10, PLAYERS -> RowViewType.TITLE_ICON_ARROW.ordinal
VERSION, SUBSCRIPTION -> RowViewType.TITLE_VALUE.ordinal VERSION, SUBSCRIPTION -> RowViewType.TITLE_VALUE.ordinal
LANGUAGE, CURRENCY, BACKUP_EMAIL -> RowViewType.TITLE_VALUE_ARROW.ordinal LANGUAGE, CURRENCY -> RowViewType.TITLE_VALUE_ARROW.ordinal
BACKUP_EMAIL -> RowViewType.TITLE_BADGE_VALUE.ordinal
FOLLOW_US -> RowViewType.ROW_FOLLOW_US.ordinal FOLLOW_US -> RowViewType.ROW_FOLLOW_US.ordinal
STOP_NOTIFICATION, SHOULD_SHOW_BLOG_TIPS, SHOW_INAPP_BADGES -> RowViewType.TITLE_SWITCH.ordinal STOP_NOTIFICATION, SHOULD_SHOW_BLOG_TIPS, SHOW_INAPP_BADGES -> RowViewType.TITLE_SWITCH.ordinal
STOP_NOTIFICATION_MESSAGE -> RowViewType.INFO.ordinal STOP_NOTIFICATION_MESSAGE -> RowViewType.INFO.ordinal

@ -23,13 +23,13 @@ class BackupOperator(var context: Context) {
init { init {
this.sessions = this.realm.where(Session::class.java).findAll() this.sessions = this.realm.where(Session::class.java).findAllAsync()
this.sessions?.addChangeListener { _ -> this.sessions?.addChangeListener { _ ->
sessionsChanged = true sessionsChanged = true
// backupIfNecessary() // backupIfNecessary()
} }
this.transactions = this.realm.where(Transaction::class.java).findAll() this.transactions = this.realm.where(Transaction::class.java).findAllAsync()
this.transactions?.addChangeListener { _ -> this.transactions?.addChangeListener { _ ->
transactionsChanged = true transactionsChanged = true
} }
@ -54,9 +54,11 @@ class BackupOperator(var context: Context) {
val sessions = this.realm.where(Session::class.java).findAll().sort("startDate") val sessions = this.realm.where(Session::class.java).findAll().sort("startDate")
val csv = ProductCSVDescriptors.pokerAnalyticsAndroid6Sessions.toCSV(sessions) val csv = ProductCSVDescriptors.pokerAnalyticsAndroid6Sessions.toCSV(sessions)
val fileName = "sessions_${Date().dateTimeFileFormatted}.csv" val fileName = "sessions_${Date().dateTimeFileFormatted}.csv"
BackupApi.backupFile(email, fileName, csv)
if (BackupApi.backupFile(context, email, fileName, csv)) {
this.sessionsChanged = false this.sessionsChanged = false
} }
}
} }
@ -67,9 +69,10 @@ class BackupOperator(var context: Context) {
val transactions = this.realm.where(Transaction::class.java).findAll().sort("date") val transactions = this.realm.where(Transaction::class.java).findAll().sort("date")
val csv = ProductCSVDescriptors.pokerAnalyticsAndroidTransactions.toCSV(transactions) val csv = ProductCSVDescriptors.pokerAnalyticsAndroidTransactions.toCSV(transactions)
val fileName = "transactions_${Date().dateTimeFileFormatted}.csv" val fileName = "transactions_${Date().dateTimeFileFormatted}.csv"
BackupApi.backupFile(email, fileName, csv) if (BackupApi.backupFile(context, email, fileName, csv)) {
this.transactionsChanged = false this.transactionsChanged = false
} }
}
} }

@ -337,6 +337,13 @@ class Preferences {
return getString(Keys.BACKUP_EMAIL, context) return getString(Keys.BACKUP_EMAIL, context)
} }
fun hasBackupEmail(context: Context): Boolean {
getString(Keys.BACKUP_EMAIL, context)?.let {
return it.isNotEmpty()
}
return false
}
fun setLanguageCode(languageCode: String, context: Context) { fun setLanguageCode(languageCode: String, context: Context) {
setString(Keys.LANGUAGE_CODE, languageCode, context) setString(Keys.LANGUAGE_CODE, languageCode, context)
} }

@ -0,0 +1,15 @@
package net.pokeranalytics.android.util.extensions
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
/***
* Returns whether the network is available or not
*/
fun Context.isNetworkAvailable(): Boolean {
val cm = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val capability = cm.getNetworkCapabilities(cm.activeNetwork)
return capability?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ?: false
}
Loading…
Cancel
Save