|
|
|
|
@ -1,4 +1,4 @@ |
|
|
|
|
package net.pokeranalytics.android.ui.fragment |
|
|
|
|
package net.pokeranalytics.android.ui.modules.datalist |
|
|
|
|
|
|
|
|
|
import android.app.Activity |
|
|
|
|
import android.content.Intent |
|
|
|
|
@ -6,6 +6,7 @@ import android.os.Bundle |
|
|
|
|
import android.view.* |
|
|
|
|
import androidx.appcompat.widget.SearchView |
|
|
|
|
import androidx.core.view.isVisible |
|
|
|
|
import androidx.lifecycle.ViewModelProviders |
|
|
|
|
import androidx.recyclerview.widget.ItemTouchHelper |
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager |
|
|
|
|
import io.realm.Realm |
|
|
|
|
@ -19,66 +20,37 @@ import net.pokeranalytics.android.model.interfaces.Identifiable |
|
|
|
|
import net.pokeranalytics.android.model.realm.Filter |
|
|
|
|
import net.pokeranalytics.android.ui.activity.EditableDataActivity |
|
|
|
|
import net.pokeranalytics.android.ui.activity.FiltersActivity |
|
|
|
|
import net.pokeranalytics.android.ui.adapter.LiveRowRepresentableDataSource |
|
|
|
|
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter |
|
|
|
|
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate |
|
|
|
|
import net.pokeranalytics.android.ui.extensions.removeMargins |
|
|
|
|
import net.pokeranalytics.android.ui.fragment.components.DeletableItemFragment |
|
|
|
|
import net.pokeranalytics.android.ui.helpers.SwipeToDeleteCallback |
|
|
|
|
import net.pokeranalytics.android.ui.view.RowRepresentable |
|
|
|
|
import net.pokeranalytics.android.ui.view.RowViewType |
|
|
|
|
import net.pokeranalytics.android.util.extensions.find |
|
|
|
|
import net.pokeranalytics.android.util.extensions.sorted |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
open class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataSource, RowRepresentableDelegate { |
|
|
|
|
open class DataListFragment : DeletableItemFragment(), RowRepresentableDelegate { |
|
|
|
|
|
|
|
|
|
val model: DataListViewModel by lazy { |
|
|
|
|
ViewModelProviders.of(requireActivity()).get(DataListViewModel::class.java) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
|
const val REQUEST_CODE_DETAILS = 1000 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private lateinit var identifiableClass: Class<out Deletable> |
|
|
|
|
|
|
|
|
|
private lateinit var dataType: LiveData |
|
|
|
|
private lateinit var items: RealmResults<out Deletable> |
|
|
|
|
private var dataListMenu: Menu? = null |
|
|
|
|
private var menu: Menu? = null |
|
|
|
|
private var searchView: SearchView? = null |
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
|
* Returns the selected item on row selection |
|
|
|
|
*/ |
|
|
|
|
private var isSelectionInstance: Boolean = false |
|
|
|
|
|
|
|
|
|
private var isSearchable: Boolean = false |
|
|
|
|
set(value) { |
|
|
|
|
field = value |
|
|
|
|
val searchMenuItem = dataListMenu?.findItem(R.id.action_search) |
|
|
|
|
searchMenuItem?.isVisible = value |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Set fragment data |
|
|
|
|
*/ |
|
|
|
|
open fun setData(dataType: Int) { |
|
|
|
|
|
|
|
|
|
this.dataType = LiveData.values()[dataType] |
|
|
|
|
this.identifiableClass = this.dataType.relatedEntity |
|
|
|
|
setToolbarTitle(this.dataType.pluralLocalizedTitle(requireContext())) |
|
|
|
|
|
|
|
|
|
this.items = this.retrieveItems(getRealm()) |
|
|
|
|
|
|
|
|
|
this.isSearchable = when (this.dataType) { |
|
|
|
|
LiveData.PLAYER, LiveData.LOCATION -> true |
|
|
|
|
else -> false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
open fun retrieveItems(realm: Realm): RealmResults<out Deletable> { |
|
|
|
|
return realm.sorted(this.identifiableClass, editableOnly = true, filterableTypeUniqueIdentifier = dataType.subType) |
|
|
|
|
return realm.sorted(this.model.identifiableClass, |
|
|
|
|
editableOnly = true, |
|
|
|
|
filterableTypeUniqueIdentifier = this.model.dataType.subType) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun deletableItems() : List<Deletable> { |
|
|
|
|
return this.items |
|
|
|
|
return this.model.items |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { |
|
|
|
|
@ -88,24 +60,44 @@ open class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataS |
|
|
|
|
|
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
|
|
|
|
super.onViewCreated(view, savedInstanceState) |
|
|
|
|
initData() |
|
|
|
|
initUI() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun initData() { |
|
|
|
|
|
|
|
|
|
val itemIds = this.model.itemIds |
|
|
|
|
val items = if (itemIds?.isNotEmpty() == true) { |
|
|
|
|
getRealm().where(this.model.identifiableClass) |
|
|
|
|
.`in`("id", itemIds) |
|
|
|
|
.sort(this.model.dataType.sortFields, this.model.dataType.sortOrders) |
|
|
|
|
.findAll() |
|
|
|
|
} else { |
|
|
|
|
this.retrieveItems(getRealm()) |
|
|
|
|
} |
|
|
|
|
this.model.setItemsList(items) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Init UI |
|
|
|
|
*/ |
|
|
|
|
private fun initUI() { |
|
|
|
|
|
|
|
|
|
val searchMenuItem = this.menu?.findItem(R.id.action_search) |
|
|
|
|
searchMenuItem?.isVisible = this.model.isSearchable |
|
|
|
|
|
|
|
|
|
setToolbarTitle(this.model.dataType.pluralLocalizedTitle(requireContext())) |
|
|
|
|
|
|
|
|
|
setDisplayHomeAsUpEnabled(true) |
|
|
|
|
|
|
|
|
|
val viewManager = LinearLayoutManager(requireContext()) |
|
|
|
|
this.dataListAdapter = RowRepresentableAdapter(this, this) |
|
|
|
|
this.dataListAdapter = RowRepresentableAdapter(this.model, this) |
|
|
|
|
|
|
|
|
|
val swipeToDelete = SwipeToDeleteCallback(dataListAdapter) { position -> |
|
|
|
|
val item = this.items[position] |
|
|
|
|
val swipeToDelete = SwipeToDeleteCallback(this.dataListAdapter) { position -> |
|
|
|
|
val item = this.model.items[position] |
|
|
|
|
if (item != null) { |
|
|
|
|
val itemId = item.id |
|
|
|
|
deleteItem(dataListAdapter, items, itemId) |
|
|
|
|
deleteItem(this.dataListAdapter, this.model.items, itemId) |
|
|
|
|
} else { |
|
|
|
|
throw PAIllegalStateException("Item with position $position not found") |
|
|
|
|
} |
|
|
|
|
@ -123,10 +115,13 @@ open class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataS |
|
|
|
|
this.addButton.setOnClickListener { |
|
|
|
|
EditableDataActivity.newInstance( |
|
|
|
|
requireContext(), |
|
|
|
|
dataType = this.dataType.ordinal, |
|
|
|
|
dataType = this.model.dataType.ordinal, |
|
|
|
|
primaryKey = null |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.addButton.isVisible = this.model.showAddButton |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun onResume() { |
|
|
|
|
@ -138,14 +133,14 @@ open class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataS |
|
|
|
|
|
|
|
|
|
menu.clear() |
|
|
|
|
inflater.inflate(R.menu.toolbar_data_list, menu) |
|
|
|
|
this.dataListMenu = menu |
|
|
|
|
this.menu = menu |
|
|
|
|
|
|
|
|
|
val searchMenuItem = menu.findItem(R.id.action_search) |
|
|
|
|
searchMenuItem.isVisible = isSearchable |
|
|
|
|
searchMenuItem.isVisible = this.model.isSearchable |
|
|
|
|
|
|
|
|
|
searchView = searchMenuItem.actionView as SearchView? |
|
|
|
|
searchView?.removeMargins() |
|
|
|
|
searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener { |
|
|
|
|
this.searchView = searchMenuItem.actionView as SearchView? |
|
|
|
|
this.searchView?.removeMargins() |
|
|
|
|
this.searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener { |
|
|
|
|
override fun onQueryTextSubmit(query: String?): Boolean { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
@ -159,22 +154,9 @@ open class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataS |
|
|
|
|
super.onCreateOptionsMenu(menu, inflater) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun rowRepresentableForPosition(position: Int): RowRepresentable? { |
|
|
|
|
return this.items[position] as RowRepresentable |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun numberOfRows(): Int { |
|
|
|
|
return this.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 onRowSelected(position: Int, row: RowRepresentable, tag: Int) { |
|
|
|
|
|
|
|
|
|
if (this.isSelectionInstance) { |
|
|
|
|
if (this.model.isSelectionInstance) { // Ends the activity and go back to previous screen |
|
|
|
|
val identifier = (row as Identifiable).id |
|
|
|
|
val intent = Intent() |
|
|
|
|
intent.putExtra(BundleKey.PRIMARY_KEY.value, identifier) |
|
|
|
|
@ -182,7 +164,7 @@ open class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataS |
|
|
|
|
this.activity?.finish() |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
when (this.dataType) { |
|
|
|
|
when (this.model.dataType) { |
|
|
|
|
LiveData.FILTER -> { |
|
|
|
|
val intent = Intent() |
|
|
|
|
intent.putExtra(FiltersActivity.IntentKey.FILTER_ID.keyName, (row as Filter).id) |
|
|
|
|
@ -191,25 +173,19 @@ open class DataListFragment : DeletableItemFragment(), LiveRowRepresentableDataS |
|
|
|
|
} |
|
|
|
|
else -> { |
|
|
|
|
val identifier = (row as Identifiable).id |
|
|
|
|
EditableDataActivity.newInstanceForResult(this, this.dataType, identifier, REQUEST_CODE_DETAILS) |
|
|
|
|
this.model.dataType.openEditActivity(this, identifier, REQUEST_CODE_DETAILS) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Update UI |
|
|
|
|
*/ |
|
|
|
|
fun updateUI(showAddButton: Boolean) { |
|
|
|
|
this.addButton.isVisible = showAddButton |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Filter the items list with the given search content |
|
|
|
|
*/ |
|
|
|
|
private fun filterItemsWithSearch(searchContent: String?) { |
|
|
|
|
this.items = getRealm().find(this.identifiableClass, searchContent) |
|
|
|
|
val items = getRealm().find(this.model.identifiableClass, searchContent) |
|
|
|
|
this.model.setItemsList(items) |
|
|
|
|
this.dataListAdapter.notifyDataSetChanged() |
|
|
|
|
} |
|
|
|
|
|