Add imports management

csv
Aurelien Hubert 6 years ago
parent d18caabbe7
commit a49afb645a
  1. 5
      app/src/main/AndroidManifest.xml
  2. 29
      app/src/main/java/net/pokeranalytics/android/model/realm/Import.kt
  3. 33
      app/src/main/java/net/pokeranalytics/android/ui/activity/ImportsHistoryActivity.kt
  4. 123
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportsHistoryFragment.kt
  5. 1
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
  6. 5
      app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt
  7. 25
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  8. 7
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt
  9. 15
      app/src/main/res/layout/activity_imports_history.xml
  10. 61
      app/src/main/res/layout/fragment_imports_history.xml
  11. 74
      app/src/main/res/layout/row_title_subtitle_action.xml

@ -129,6 +129,11 @@
android:launchMode="singleTop"
android:screenOrientation="portrait" />
<activity
android:name="net.pokeranalytics.android.ui.activity.ImportsHistoryActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
<activity
android:name="net.pokeranalytics.android.ui.activity.FiltersActivity"
android:launchMode="singleTop"

@ -1,11 +1,16 @@
package net.pokeranalytics.android.model.realm
import android.content.Context
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.Ignore
import io.realm.kotlin.deleteFromRealm
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import java.util.*
open class Import : RealmObject() {
open class Import : RealmObject(), RowRepresentable {
var date: Date = Date()
@ -13,12 +18,25 @@ open class Import : RealmObject() {
var identifiableObjects: RealmList<IdentifiableObject> = RealmList()
fun delete() {
@Ignore
override val isClickable: Boolean = false
this.realm.executeTransaction {
@Ignore
override val viewType: Int = RowViewType.TITLE_SUBTITLE_ACTION.ordinal
this.identifiableObjects.forEach {
@Ignore
override val imageRes: Int? = R.drawable.ic_outline_delete
@Ignore
override val imageClickable: Boolean? = true
override fun getDisplayName(context: Context): String {
return fileName
}
fun delete() {
this.realm.executeTransaction {
this.identifiableObjects.forEach {
val realmModel = it.realmModel
when (realmModel) {
is Session -> {
@ -26,12 +44,9 @@ open class Import : RealmObject() {
}
else -> {}
}
realmModel?.deleteFromRealm()
}
}
}
}

@ -0,0 +1,33 @@
package net.pokeranalytics.android.ui.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
class ImportsHistoryActivity : PokerAnalyticsActivity() {
companion object {
fun newInstance(context: Context) {
val intent = Intent(context, ImportsHistoryActivity::class.java)
context.startActivity(intent)
}
/**
* Create a new instance for result
*/
fun newInstanceForResult(fragment: Fragment, requestCode: Int) {
val intent = Intent(fragment.requireContext(), ImportsHistoryActivity::class.java)
fragment.startActivityForResult(intent, requestCode)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_imports_history)
}
}

@ -0,0 +1,123 @@
package net.pokeranalytics.android.ui.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.RealmResults
import io.realm.Sort
import io.realm.kotlin.where
import kotlinx.android.synthetic.main.fragment_data_list.*
import net.pokeranalytics.android.BuildConfig
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Import
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.extensions.showAlertDialog
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.util.extensions.shortDateTime
import java.util.*
class ImportsHistoryFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {
companion object {
val rowRepresentation: List<RowRepresentable> by lazy {
val rows = ArrayList<RowRepresentable>()
//rows.addAll(mostUsedCurrencies)
//rows.add(SeparatorRow())
//rows.addAll(availableCurrencies)
rows
}
}
private lateinit var dataListAdapter: RowRepresentableAdapter
private lateinit var items: RealmResults<Import>
override fun rowRepresentableForPosition(position: Int): RowRepresentable? {
return this.items[position] as RowRepresentable
}
override fun numberOfRows(): Int {
return items.size
}
override fun viewTypeForPosition(position: Int): Int {
val viewType = (this.items[position] as RowRepresentable).viewType
return if (viewType != -1) viewType else RowViewType.DATA.ordinal
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_currencies, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initData()
initUI()
}
override fun adapterRows(): List<RowRepresentable>? {
return rowRepresentation
}
override fun stringForRow(row: RowRepresentable): String {
if (row is Import) {
return row.date.shortDateTime()
}
return super.stringForRow(row)
}
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
if (row is Import && fromAction) {
showAlertDialog(message = R.string.import_deletion, showCancelButton = true, positiveAction = {
//TODO: Check the deletion works correctly
row.delete()
dataListAdapter.notifyItemRemoved(position)
})
}
}
private fun initData() {
items = getRealm().where<Import>().findAll().sort("date", Sort.DESCENDING)
if (BuildConfig.DEBUG && items.size == 0) {
val calendar = Calendar.getInstance()
getRealm().executeTransaction {
for (i in 0..2) {
val import = Import()
import.fileName = "Import_${i}_Android.csv"
import.date = calendar.time
it.copyToRealm(import)
calendar.add(Calendar.DAY_OF_MONTH, -1)
}
}
}
}
/**
* Init UI
*/
private fun initUI() {
setDisplayHomeAsUpEnabled(true)
setToolbarTitle(getString(R.string.imports_history))
val viewManager = LinearLayoutManager(requireContext())
dataListAdapter = RowRepresentableAdapter(this, this)
recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataListAdapter
}
}
}

@ -126,6 +126,7 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta
SettingRow.CONTACT_US -> parentActivity?.openContactMail(R.string.contact)
SettingRow.BUG_REPORT -> parentActivity?.openContactMail(R.string.bug_report_subject, Realm.getDefaultInstance().path)
SettingRow.CURRENCY -> CurrenciesActivity.newInstanceForResult(this@SettingsFragment, RequestCode.CURRENCY.value)
SettingRow.IMPORTS_HISTORY -> ImportsHistoryActivity.newInstance(requireContext())
SettingRow.FOLLOW_US -> {
when (position) {
0 -> parentActivity?.openUrl(URL.BLOG.value)

@ -76,6 +76,11 @@ interface Displayable : Localizable {
get() {
return null
}
val isClickable: Boolean
get() {
return true
}
}
/**

@ -68,6 +68,7 @@ enum class RowViewType(private var layoutRes: Int) {
TITLE_VALUE(R.layout.row_title_value),
TITLE_VALUE_ARROW(R.layout.row_title_value_arrow),
TITLE_VALUE_ACTION(R.layout.row_title_value_action),
TITLE_SUBTITLE_ACTION(R.layout.row_title_subtitle_action),
TITLE_SWITCH(R.layout.row_title_switch),
TITLE_GRID(R.layout.row_bottom_sheet_grid_title),
DATA(R.layout.row_title),
@ -102,8 +103,8 @@ enum class RowViewType(private var layoutRes: Int) {
// Row View Holder
HEADER_TITLE, HEADER_TITLE_VALUE, HEADER_TITLE_AMOUNT, HEADER_TITLE_AMOUNT_BIG, LOCATION_TITLE,
INFO, TITLE, TITLE_ARROW, TITLE_ICON_ARROW, TITLE_VALUE, TITLE_VALUE_ARROW, TITLE_VALUE_ACTION, TITLE_GRID,
TITLE_SWITCH, TITLE_CHECK, TITLE_VALUE_CHECK,
INFO, TITLE, TITLE_ARROW, TITLE_ICON_ARROW, TITLE_VALUE, TITLE_VALUE_ARROW, TITLE_VALUE_ACTION, TITLE_SUBTITLE_ACTION,
TITLE_GRID, TITLE_SWITCH, TITLE_CHECK, TITLE_VALUE_CHECK,
DATA, BOTTOM_SHEET_DATA, LOADER -> RowViewHolder(layout)
// Row Session
@ -244,18 +245,20 @@ enum class RowViewType(private var layoutRes: Int) {
}
// Listener
val listener = View.OnClickListener {
itemView.findViewById<SwitchCompat?>(R.id.switchView)?.let {
if (adapter.dataSource.isEnabled(row)) {
it.isChecked = !it.isChecked
if (row.isClickable) {
val listener = View.OnClickListener {
itemView.findViewById<SwitchCompat?>(R.id.switchView)?.let {
if (adapter.dataSource.isEnabled(row)) {
it.isChecked = !it.isChecked
}
} ?: run {
adapter.delegate?.onRowSelected(position, row)
}
} ?: run {
adapter.delegate?.onRowSelected(position, row)
}
}
itemView.findViewById<View?>(R.id.container)?.setOnClickListener(listener)
}
itemView.findViewById<View?>(R.id.container)?.setOnClickListener(listener)
}
}
}
// Switch

@ -26,6 +26,9 @@ enum class SettingRow : RowRepresentable {
LANGUAGE,
CURRENCY,
// Import & Export
IMPORTS_HISTORY,
// Data management
CUSTOM_FIELD,
BANKROLL,
@ -62,6 +65,9 @@ enum class SettingRow : RowRepresentable {
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.preferences))
rows.addAll(arrayListOf(CURRENCY))
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.data))
rows.addAll(arrayListOf(IMPORTS_HISTORY))
rows.add(
CustomizableRowRepresentable(
customViewType = RowViewType.HEADER_TITLE,
@ -95,6 +101,7 @@ enum class SettingRow : RowRepresentable {
TERMS_OF_USE -> R.string.terms_of_use
FOLLOW_US -> R.string.follow_us
LANGUAGE -> R.string.language
IMPORTS_HISTORY -> R.string.imports_history
CURRENCY -> R.string.currency
GDPR -> R.string.gdpr
else -> null

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<fragment
android:id="@+id/importsHistoryFragment"
android:name="net.pokeranalytics.android.ui.fragment.ImportsHistoryFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/fragment_imports_history" />
</LinearLayout>

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:id="@+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="128dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:collapsedTitleTextAppearance="@style/PokerAnalyticsTheme.Toolbar.CollapsedTitleAppearance"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="bottom"
app:expandedTitleMarginStart="72dp"
app:expandedTitleTextAppearance="@style/PokerAnalyticsTheme.Toolbar.ExpandedTitleAppearance"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:title="Poker Analytics"
app:titleTextColor="@color/white" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/layout_swipe_to_delete" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/foreground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/gray_dark"
android:foreground="?selectableItemBackground">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/title"
style="@style/PokerAnalyticsTheme.TextView.RowTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toStartOf="@+id/action"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/guidelineStart"
app:layout_constraintTop_toTopOf="parent"
tools:text="Title" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/value"
style="@style/PokerAnalyticsTheme.TextView.RowValue"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/action"
app:layout_constraintStart_toStartOf="@+id/guidelineStart"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="Value" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/action"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="?selectableItemBackgroundBorderless"
android:padding="4dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/guidelineEnd"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_close"
tools:visibility="visible" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="16dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineEnd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="16dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
Loading…
Cancel
Save