diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index c519214e..c494ede4 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -4,10 +4,12 @@ import android.text.InputType import io.realm.* import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey +import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.SessionInterface import net.pokeranalytics.android.ui.adapter.components.* import net.pokeranalytics.android.ui.fragment.components.BottomSheetData import net.pokeranalytics.android.util.data.sessionDao +import net.pokeranalytics.android.util.short import java.util.* import kotlin.collections.ArrayList @@ -141,12 +143,23 @@ open class Session : RealmObject(), SessionInterface, DynamicRowDelegate, Displa SessionRow.GAME -> game?.title ?: "--" SessionRow.LOCATION -> location?.title ?: "--" SessionRow.BANKROLL -> bankroll?.title ?: "--" - SessionRow.DATE -> if (timeFrame != null) timeFrame?.startDate.toString() else "--" + SessionRow.START_DATE -> if (timeFrame != null) timeFrame?.startDate?.short() ?: "--" else "--" + SessionRow.END_DATE -> if (timeFrame != null) timeFrame?.endDate?.short() ?: "--" else "--" SessionRow.COMMENT -> if (comment.isNotEmpty()) comment else "--" else -> "--" } } + override fun actionIconForRow(row: DynamicRowInterface): Int? { + return when (row) { + SessionRow.START_DATE, SessionRow.END_DATE -> { + R.drawable.ic_close_white_24dp + } + else -> null + } + } + + override var title: String = "Change that: $creationDate" override val primaryKey: String get() = this.id @@ -165,10 +178,6 @@ open class Session : RealmObject(), SessionInterface, DynamicRowDelegate, Displa SessionRow.BANKROLL -> { data.add(BottomSheetData(bankroll, "", 0, DataList.BANKROLL.items(realm))) } - SessionRow.DATE -> { - data.add(BottomSheetData(timeFrame?.startDate, "Start date")) - data.add(BottomSheetData(timeFrame?.endDate, "End date")) - } SessionRow.BLINDS -> { data.add(BottomSheetData(cgSmallBlind, "Small blind", InputType.TYPE_CLASS_NUMBER)) data.add(BottomSheetData(cgBigBlind, "Big blind", InputType.TYPE_CLASS_NUMBER)) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/DynamicListAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/DynamicListAdapter.kt index 83778819..ee87cb0e 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/DynamicListAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/DynamicListAdapter.kt @@ -5,15 +5,24 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView interface EditableDataDelegate { - fun setValue(value: Any, row: DynamicRowInterface) + fun setValue(value: Any, row: DynamicRowInterface) } interface DynamicRowDelegate { - fun adapterRows() : ArrayList + fun adapterRows(): ArrayList - fun boolForRow(row: DynamicRowInterface) : Boolean { return false } - fun stringForRow(row: DynamicRowInterface) : String { return "" } + fun boolForRow(row: DynamicRowInterface): Boolean { + return false + } + + fun stringForRow(row: DynamicRowInterface): String { + return "" + } + + fun actionIconForRow(row: DynamicRowInterface): Int? { + return 0 + } /** * Manages: @@ -27,36 +36,44 @@ interface DynamicRowDelegate { } interface DynamicRowCallback { - fun onRowSelected(row: DynamicRowInterface) + fun onRowSelected(row: DynamicRowInterface) {} + fun onActionSelected(row: DynamicRowInterface) {} } -class DynamicListAdapter(var delegate: DynamicRowDelegate, var callBackDelegate: DynamicRowCallback? = null) : RecyclerView.Adapter() { +class DynamicListAdapter(var delegate: DynamicRowDelegate, var callBackDelegate: DynamicRowCallback? = null) : + RecyclerView.Adapter() { + + private var rows: ArrayList = ArrayList() + + init { + this.rows = delegate.adapterRows() + } + + override fun getItemViewType(position: Int): Int { + return this.rows[position].viewType + } - private var rows: ArrayList = ArrayList() + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val rowViewType: RowViewType = RowViewType.values()[viewType] + return rowViewType.viewHolder(parent) + } - init { - this.rows = delegate.adapterRows() - } + override fun getItemCount(): Int { + return this.rows.size + } - override fun getItemViewType(position: Int): Int { - return this.rows[position].viewType - } + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val dynamicRow = this.rows[position] - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - val rowViewType: RowViewType = RowViewType.values()[viewType] - return rowViewType.viewHolder(parent) - } + val listener = View.OnClickListener { + callBackDelegate?.onRowSelected(dynamicRow) + } - override fun getItemCount(): Int { - return this.rows.size - } + val actionListener = View.OnClickListener { + callBackDelegate?.onActionSelected(dynamicRow) + } - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - val dynamicRow = this.rows[position] - val listener = View.OnClickListener { - callBackDelegate?.onRowSelected(dynamicRow) - } - (holder as DynamicHolder).bind(dynamicRow, this.delegate, listener) - } + (holder as DynamicHolder).bind(dynamicRow, this.delegate, listener, actionListener) + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/DynamicRowInterface.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/DynamicRowInterface.kt index 0a350580..daea6641 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/DynamicRowInterface.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/DynamicRowInterface.kt @@ -38,7 +38,8 @@ enum class SessionRow(val resId: Int) : DynamicRowInterface { BLINDS(R.string.blinds), LOCATION(R.string.location), BANKROLL(R.string.bankroll), - DATE(R.string.date), + START_DATE(R.string.start_date), + END_DATE(R.string.end_date), COMMENT(R.string.comment); override fun localizedTitle(context: Context): String { @@ -48,7 +49,8 @@ enum class SessionRow(val resId: Int) : DynamicRowInterface { override val viewType: Int get() { return when (this) { - BLINDS, GAME, DATE, BANKROLL, LOCATION, COMMENT -> RowViewType.TITLE_VALUE.ordinal + BLINDS, GAME, BANKROLL, LOCATION, COMMENT -> RowViewType.TITLE_VALUE.ordinal + START_DATE, END_DATE -> RowViewType.TITLE_VALUE_ACTION.ordinal } } @@ -59,8 +61,8 @@ enum class SessionRow(val resId: Int) : DynamicRowInterface { GAME -> BottomSheetType.LIST LOCATION -> BottomSheetType.LIST BANKROLL -> BottomSheetType.LIST - DATE -> BottomSheetType.DATE COMMENT -> BottomSheetType.EDIT_TEXT + else -> BottomSheetType.NONE } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/RowViewType.kt index 89782d78..7886c073 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/RowViewType.kt @@ -4,64 +4,89 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.row_session.view.* +import kotlinx.android.synthetic.main.row_title_value_action.view.* import net.pokeranalytics.android.R interface DynamicHolder { - fun bind(row: DynamicRowInterface, delegate: DynamicRowDelegate? = null, listener: View.OnClickListener) + fun bind(row: DynamicRowInterface, delegate: DynamicRowDelegate? = null, listener: View.OnClickListener, actionListener: View.OnClickListener? = null) {} } enum class RowViewType { - HEADER, - EDIT_TEXT, - TITLE, - TITLE_VALUE; + HEADER, + EDIT_TEXT, + TITLE, + TITLE_VALUE, + TITLE_VALUE_ACTION; - inner class FakeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), DynamicHolder { - override fun bind(row: DynamicRowInterface, delegate: DynamicRowDelegate?, listener: View.OnClickListener) { - } - } + inner class FakeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), DynamicHolder { + override fun bind(row: DynamicRowInterface, delegate: DynamicRowDelegate?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { + } + } - inner class TitleValueViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), DynamicHolder { - override fun bind(row: DynamicRowInterface, delegate: DynamicRowDelegate?, listener: View.OnClickListener) { - itemView.title.text = row.localizedTitle(itemView.context) + inner class TitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), DynamicHolder { + override fun bind(row: DynamicRowInterface, delegate: DynamicRowDelegate?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { + itemView.title.text = row.localizedTitle(itemView.context) + itemView.container.setOnClickListener(listener) + } + } - delegate?.let { - itemView.value.text = it.stringForRow(row) - } - itemView.container.setOnClickListener(listener) - } - } + inner class TitleValueViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), DynamicHolder { + override fun bind(row: DynamicRowInterface, delegate: DynamicRowDelegate?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { + itemView.title.text = row.localizedTitle(itemView.context) - inner class TitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), DynamicHolder { - override fun bind(row: DynamicRowInterface, delegate: DynamicRowDelegate?, listener: View.OnClickListener) { - itemView.title.text = row.localizedTitle(itemView.context) - itemView.container.setOnClickListener(listener) - } - } + delegate?.let { + itemView.value.text = it.stringForRow(row) + } + itemView.container.setOnClickListener(listener) + } + } + inner class TitleValueActionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), DynamicHolder { + override fun bind(row: DynamicRowInterface, delegate: DynamicRowDelegate?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { + itemView.title.text = row.localizedTitle(itemView.context) + delegate?.let { rowDelegate -> - fun viewHolder(parent: ViewGroup): RecyclerView.ViewHolder { - return when (this) { - TITLE_VALUE -> TitleValueViewHolder( - LayoutInflater.from(parent.context).inflate( - R.layout.row_title_value, - parent, - false - ) - ) - TITLE -> TitleViewHolder( - LayoutInflater.from(parent.context).inflate( - R.layout.row_title, - parent, - false - ) - ) + val value = rowDelegate.stringForRow(row) + itemView.value.text = value + itemView.action.visibility = if (value == "--") View.GONE else View.VISIBLE + rowDelegate.actionIconForRow(row)?.let {icon -> + itemView.action.setImageResource(icon) + } + } + itemView.container.setOnClickListener(listener) + itemView.action.setOnClickListener(actionListener) + } + } - else -> FakeViewHolder(parent) - } - } + + fun viewHolder(parent: ViewGroup): RecyclerView.ViewHolder { + return when (this) { + TITLE -> TitleViewHolder( + LayoutInflater.from(parent.context).inflate( + R.layout.row_title, + parent, + false + ) + ) + TITLE_VALUE -> TitleValueViewHolder( + LayoutInflater.from(parent.context).inflate( + R.layout.row_title_value, + parent, + false + ) + ) + TITLE_VALUE_ACTION -> TitleValueActionViewHolder( + LayoutInflater.from(parent.context).inflate( + R.layout.row_title_value_action, + parent, + false + ) + ) + + else -> FakeViewHolder(parent) + } + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/NewSessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/NewSessionFragment.kt index 0a7f4d55..5a0f1db0 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/NewSessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/NewSessionFragment.kt @@ -17,7 +17,9 @@ import net.pokeranalytics.android.ui.adapter.components.DynamicRowInterface import net.pokeranalytics.android.ui.adapter.components.SessionRow import net.pokeranalytics.android.ui.fragment.components.BottomSheetDelegate import net.pokeranalytics.android.ui.fragment.components.BottomSheetFragment +import net.pokeranalytics.android.ui.fragment.components.DateTimePickerManager import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment +import java.util.* class NewSessionFragment : PokerAnalyticsFragment(), DynamicRowCallback, BottomSheetDelegate { @@ -36,7 +38,15 @@ class NewSessionFragment : PokerAnalyticsFragment(), DynamicRowCallback, BottomS override fun onRowSelected(row: DynamicRowInterface) { val data = currentSession.getBottomSheetData(row, getRealm()) - BottomSheetFragment.create(fragmentManager, row, this, data) + when(row) { + SessionRow.START_DATE -> DateTimePickerManager.create(requireContext(), row, this, currentSession.timeFrame?.startDate) + SessionRow.END_DATE -> DateTimePickerManager.create(requireContext(), row, this, currentSession.timeFrame?.endDate) + else -> BottomSheetFragment.create(fragmentManager, row, this, data) + } + } + + override fun onActionSelected(row: DynamicRowInterface) { + Toast.makeText(requireContext(), "Action for row: $row", Toast.LENGTH_SHORT).show() } override fun clickOnAdd(row: DynamicRowInterface) { @@ -70,11 +80,21 @@ class NewSessionFragment : PokerAnalyticsFragment(), DynamicRowCallback, BottomS SessionRow.GAME -> if (value is Game) currentSession.game = value SessionRow.BANKROLL -> if (value is Bankroll) currentSession.bankroll = value SessionRow.LOCATION -> if (value is Location) currentSession.location = value + SessionRow.COMMENT -> if (value is String) currentSession.comment = value SessionRow.BLINDS -> if (value is ArrayList<*>) { currentSession.cgSmallBlind = (value[0] as String? ?: "0").toDouble() currentSession.cgBigBlind = (value[1] as String? ?: "0").toDouble() } - SessionRow.COMMENT -> if (value is String) currentSession.comment = value + SessionRow.START_DATE -> if (value is Date) { + val timeFrame = currentSession.timeFrame ?: TimeFrame() + timeFrame.setDate(value, null) + currentSession.timeFrame = timeFrame + } + SessionRow.END_DATE -> if (value is Date) { + val timeFrame = currentSession.timeFrame ?: TimeFrame() + timeFrame.setDate(timeFrame.startDate, value) + currentSession.timeFrame = timeFrame + } } sessionAdapter.notifyItemChanged(SessionRow.values().indexOf(row)) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/BottomSheetDateFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/BottomSheetDateFragment.kt index e31aecff..c49600fb 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/BottomSheetDateFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/BottomSheetDateFragment.kt @@ -4,12 +4,10 @@ import android.app.DatePickerDialog import android.app.TimePickerDialog import android.os.Bundle import android.text.format.DateFormat -import android.view.LayoutInflater import android.view.View import android.widget.DatePicker import android.widget.TimePicker import kotlinx.android.synthetic.main.bottom_sheet_date.* -import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.* import timber.log.Timber import java.util.* @@ -79,9 +77,9 @@ class BottomSheetDateFragment : BottomSheetFragment(), DatePickerDialog.OnDateSe */ private fun initUI() { - LayoutInflater.from(requireContext()).inflate(net.pokeranalytics.android.R.layout.bottom_sheet_date, view?.bottomSheetContainer, true) + //LayoutInflater.from(requireContext()).inflate(net.pokeranalytics.android.R.layout.bottom_sheet_date, view?.bottomSheetContainer, true) - setAddButtonVisible(false) + //setAddButtonVisible(false) startDate.setOnClickListener { currentDateEdition = DateEdition.START @@ -93,6 +91,9 @@ class BottomSheetDateFragment : BottomSheetFragment(), DatePickerDialog.OnDateSe showDatePicker() } + currentDateEdition = DateEdition.START + showDatePicker() + } /** diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DateTimeDialogFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DateTimeDialogFragment.kt new file mode 100644 index 00000000..4bd4c822 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DateTimeDialogFragment.kt @@ -0,0 +1,77 @@ +package net.pokeranalytics.android.ui.fragment.components + +import android.app.DatePickerDialog +import android.app.TimePickerDialog +import android.content.Context +import android.text.format.DateFormat +import android.widget.DatePicker +import android.widget.TimePicker +import net.pokeranalytics.android.ui.adapter.components.DynamicRowInterface +import java.util.* + +class DateTimePickerManager : DatePickerDialog.OnDateSetListener, + TimePickerDialog.OnTimeSetListener { + + private var context: Context? = null + private val calendar = Calendar.getInstance() + + lateinit var row: DynamicRowInterface + lateinit var bottomSheetDelegate: BottomSheetDelegate + + + companion object { + fun create( + context: Context, + row: DynamicRowInterface, + bottomSheetDelegate: BottomSheetDelegate, + date: Date? + ) : DateTimePickerManager { + val dateTimePickerManager = DateTimePickerManager() + dateTimePickerManager.context = context + dateTimePickerManager.showDatePicker() + dateTimePickerManager.row = row + dateTimePickerManager.bottomSheetDelegate = bottomSheetDelegate + return dateTimePickerManager + } + } + + + override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) { + calendar.set(Calendar.YEAR, year) + calendar.set(Calendar.MONTH, month) + calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth) + showTimePicker() + } + + override fun onTimeSet(view: TimePicker?, hourOfDay: Int, minute: Int) { + calendar.set(Calendar.HOUR_OF_DAY, hourOfDay) + calendar.set(Calendar.MINUTE, minute) + bottomSheetDelegate.setValue(calendar.time, row) + } + + /** + * Show the date picker + */ + private fun showDatePicker() { + val year = calendar.get(Calendar.YEAR) + val month = calendar.get(Calendar.MONTH) + val day = calendar.get(Calendar.DAY_OF_MONTH) + context?.let { + val datePickerDialog = DatePickerDialog(it, this, year, month, day) + datePickerDialog.show() + } + } + + /** + * Show the time picker + */ + private fun showTimePicker() { + val hour = calendar.get(Calendar.YEAR) + val minute = calendar.get(Calendar.MONTH) + context?.let { + val timePickerDialog = TimePickerDialog(context, this, hour, minute, DateFormat.is24HourFormat(context)) + timePickerDialog.show() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/util/Extensions.kt b/app/src/main/java/net/pokeranalytics/android/util/Extensions.kt new file mode 100644 index 00000000..97b56b9c --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/util/Extensions.kt @@ -0,0 +1,17 @@ +package net.pokeranalytics.android.util + +import java.text.DateFormat +import java.util.* + + +fun Date.short(): String { + return DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(this) +} + +fun Date.medium(): String { + return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).format(this) +} + +fun Date.full(): String { + return DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(this) +} \ No newline at end of file diff --git a/app/src/main/res/layout/row_title_value_action.xml b/app/src/main/res/layout/row_title_value_action.xml new file mode 100644 index 00000000..0eadbb4c --- /dev/null +++ b/app/src/main/res/layout/row_title_value_action.xml @@ -0,0 +1,56 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 457e0d52..fa9a56b3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,6 +9,8 @@ Blinds Game Date + Start date + End date Location Session Tournament Type