Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
physphil committed Sep 23, 2018
2 parents 0a43b48 + 4dcf752 commit 14190d7
Show file tree
Hide file tree
Showing 16 changed files with 370 additions and 168 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId "com.physphil.android.remindme"
minSdkVersion 21
targetSdkVersion 27
versionCode 9000
versionName "0.9"
versionCode 9030
versionName "0.9.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,46 @@ import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Button
import android.widget.DatePicker
import android.widget.EditText
import android.widget.TextView
import android.widget.TimePicker
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import butterknife.OnTextChanged
import com.physphil.android.remindme.BaseActivity
import com.physphil.android.remindme.R
import com.physphil.android.remindme.RemindMeApplication
import com.physphil.android.remindme.models.Recurrence
import com.physphil.android.remindme.reminders.list.DeleteReminderDialogFragment
import com.physphil.android.remindme.ui.ReminderEntryButton
import com.physphil.android.remindme.ui.ReminderEntryField
import com.physphil.android.remindme.util.getDisplayDate
import com.physphil.android.remindme.util.getDisplayTime
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import java.util.Calendar

/**
* Create a new observableReminder or edit and existing one.
* Create a new [Reminder] or edit and existing one.
*
* Copyright (c) 2017 Phil Shadlyn
*/
class ReminderActivity : BaseActivity(), TimePickerDialog.OnTimeSetListener,
DatePickerDialog.OnDateSetListener, RecurrencePickerDialog.OnRecurrenceSetListener,
DeleteReminderDialogFragment.Listener {

@BindView(R.id.reminder_title_text)
lateinit var titleText: EditText
@BindView(R.id.reminder_title)
lateinit var titleView: ReminderEntryField

@BindView(R.id.reminder_body_text)
lateinit var bodyText: EditText
@BindView(R.id.reminder_body)
lateinit var bodyView: ReminderEntryField

@BindView(R.id.reminder_time_btn)
lateinit var timeText: Button
@BindView(R.id.reminder_time)
lateinit var timeView: ReminderEntryButton

@BindView(R.id.reminder_date_btn)
lateinit var dateText: Button
@BindView(R.id.reminder_date)
lateinit var dateView: ReminderEntryButton

@BindView(R.id.reminder_repeat_btn)
lateinit var repeatText: Button
@BindView(R.id.reminder_recurrence)
lateinit var recurrenceView: ReminderEntryButton

/** A [CompositeDisposable] to contain all active subscriptions. Should be cleared when Activity is destroyed */
private val disposables = CompositeDisposable()
Expand All @@ -69,7 +65,7 @@ class ReminderActivity : BaseActivity(), TimePickerDialog.OnTimeSetListener,
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_reminder)
setHomeArrowBackNavigation()
ButterKnife.bind(this)
bindViews()
bindViewModel()
}

Expand All @@ -78,6 +74,30 @@ class ReminderActivity : BaseActivity(), TimePickerDialog.OnTimeSetListener,
disposables.clear()
}

private fun bindViews() {
ButterKnife.bind(this)

titleView.setOnTextChangedListener {
viewModel.updateTitle(it)
}

bodyView.setOnTextChangedListener {
viewModel.updateBody(it)
}

timeView.setOnClickListener {
viewModel.openTimePicker()
}

dateView.setOnClickListener {
viewModel.openDatePicker()
}

recurrenceView.setOnClickListener {
viewModel.openRecurrencePicker()
}
}

private fun bindViewModel() {
// Will either be called immediately with stored value, or will be updated upon successful read from database
disposables.add(viewModel.observableReminder
Expand All @@ -86,59 +106,66 @@ class ReminderActivity : BaseActivity(), TimePickerDialog.OnTimeSetListener,
.subscribe({
// on success. Save Reminder in viewmodel and update UI
viewModel.reminder = it
titleText.setText(it.title, TextView.BufferType.EDITABLE)
titleText.setSelection(it.title.length)
bodyText.setText(it.body, TextView.BufferType.EDITABLE)
timeText.text = it.getDisplayTime(this)
dateText.text = it.getDisplayDate(this)
repeatText.setText(it.recurrence.displayString)
titleView.setText(it.title)
bodyView.setText(it.body)
timeView.setText(it.getDisplayTime(this))
dateView.setText(it.getDisplayDate(this))
recurrenceView.setText(it.recurrence.displayString)

// Clear any notifications for this Reminder
notificationManager.cancel(it.notificationId)
}, {
// on error
}))

viewModel.getReminderTime().observe(this, Observer { it?.let { timeText.text = it } })
viewModel.getReminderDate().observe(this, Observer { it?.let { dateText.text = it } })
viewModel.getReminderRecurrence().observe(this, Observer { it?.let { repeatText.setText(it) } })
viewModel.getReminderTime().observe(this, Observer { it?.let { timeView.setText(it) } })
viewModel.getReminderDate().observe(this, Observer { it?.let { dateView.setText(it) } })
viewModel.getReminderRecurrence().observe(this, Observer { it?.let { recurrenceView.setText(it) } })
viewModel.getToolbarTitle().observe(this, Observer { it?.let { setToolbarTitle(it) } })
viewModel.clearNotificationEvent.observe(this, Observer { it?.let { notificationManager.cancel(it) } })
viewModel.confirmDeleteEvent.observe(this, Observer { DeleteReminderDialogFragment.newInstance().show(supportFragmentManager, DeleteReminderDialogFragment.TAG) })
viewModel.closeActivityEvent.observe(this, Observer { finish() })
}

@OnTextChanged(R.id.reminder_title_text)
fun onTitleChanged(text: CharSequence) {
viewModel.updateTitle(text.toString())
}

@OnTextChanged(R.id.reminder_body_text)
fun onBodyChanged(text: CharSequence) {
viewModel.updateBody(text.toString())
}
viewModel.clearNotificationEvent.observe(this, Observer {
it?.let {
notificationManager.cancel(it)
}
})

viewModel.confirmDeleteEvent.observe(this, Observer {
DeleteReminderDialogFragment.newInstance().show(supportFragmentManager, DeleteReminderDialogFragment.TAG)
})

viewModel.closeActivityEvent.observe(this, Observer {
finish()
})

viewModel.openTimePickerEvent.observe(this, Observer {
it?.let {
TimePickerDialog(this,
R.style.Pickers,
this,
it.hour,
it.minute,
false).show()
}
})

@OnClick(R.id.reminder_time_btn, R.id.reminder_time_icon)
fun onTimeClicked() {
val calendar = viewModel.reminder.time
TimePickerDialog(this, R.style.Pickers, this,
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE), false).show()
}
viewModel.openDatePickerEvent.observe(this, Observer {
it?.let {
DatePickerDialog(this,
R.style.Pickers,
this,
it.year,
it.month,
it.day).show()

@OnClick(R.id.reminder_date_btn, R.id.reminder_date_icon)
fun onDateClicked() {
val calendar = viewModel.reminder.time
DatePickerDialog(this, R.style.Pickers, this,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)).show()
}
}
})

@OnClick(R.id.reminder_repeat_btn, R.id.reminder_repeat_icon)
fun onRecurrenceClicked() {
RecurrencePickerDialog.newInstance(viewModel.reminder.recurrence)
.show(supportFragmentManager, RecurrencePickerDialog.TAG)
viewModel.openRecurrencePickerEvent.observe(this, Observer {
it?.let {
RecurrencePickerDialog.newInstance(it)
.show(supportFragmentManager, RecurrencePickerDialog.TAG)
}
})
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.ViewModel
import android.content.Context
import android.support.annotation.VisibleForTesting
import android.view.MenuItem
import com.physphil.android.remindme.R
import com.physphil.android.remindme.data.ReminderRepo
Expand All @@ -30,6 +31,9 @@ class ReminderViewModel(id: String? = null, private val repo: ReminderRepo, priv
val clearNotificationEvent = SingleLiveEvent<Int>()
val confirmDeleteEvent = SingleLiveEvent<Void>()
val closeActivityEvent = SingleLiveEvent<Void>()
val openTimePickerEvent = SingleLiveEvent<Time>()
val openDatePickerEvent = SingleLiveEvent<Date>()
val openRecurrencePickerEvent = SingleLiveEvent<Recurrence>()

private val reminderTime = MutableLiveData<String>()
private val reminderDate = MutableLiveData<String>()
Expand Down Expand Up @@ -71,6 +75,29 @@ class ReminderViewModel(id: String? = null, private val repo: ReminderRepo, priv
reminderRecurrence.value = recurrence.displayString
}

fun openTimePicker() {
with(reminder.time) {
openTimePickerEvent.postValue(Time(
hour = get(Calendar.HOUR_OF_DAY),
minute = get(Calendar.MINUTE)
))
}
}

fun openDatePicker() {
with(reminder.time) {
openDatePickerEvent.postValue(Date(
year = get(Calendar.YEAR),
month = get(Calendar.MONTH),
day = get(Calendar.DAY_OF_MONTH)
))
}
}

fun openRecurrencePicker() {
openRecurrencePickerEvent.postValue(reminder.recurrence)
}

fun saveReminder() {
// Set all second fields to 0 before saving, so alarm happens at exactly the specified time
reminder.time.set(Calendar.SECOND, 0)
Expand Down Expand Up @@ -114,4 +141,7 @@ class ReminderViewModel(id: String? = null, private val repo: ReminderRepo, priv
reminder.body,
reminder.recurrence.id)
}

data class Time(val hour: Int, val minute: Int)
data class Date(val year: Int, val month: Int, val day: Int)
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ class ReminderListAdapter : RecyclerView.Adapter<ReminderListAdapter.ViewHolder>

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return if (viewType == VIEW_TYPE_HEADER) {
val view = LayoutInflater.from(parent.context).inflate(R.layout.header_reminder_list, parent, false)
val view = LayoutInflater.from(parent.context).inflate(R.layout.view_header_reminder_list, parent, false)
HeaderViewHolder(view)
}
else {
val view = LayoutInflater.from(parent.context).inflate(R.layout.row_reminder_list, parent, false)
val view = LayoutInflater.from(parent.context).inflate(R.layout.view_row_reminder_list, parent, false)
ReminderViewHolder(view)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ProgressSpinner : ConstraintLayout {
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
val view = inflate(context, R.layout.progress_spinner, this)
val view = inflate(context, R.layout.view_progress_spinner, this)
ButterKnife.bind(this, view)

attrs?.let {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.physphil.android.remindme.ui

import android.content.Context
import android.support.annotation.DrawableRes
import android.support.constraint.ConstraintLayout
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.Button
import android.widget.ImageView
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import com.physphil.android.remindme.R

class ReminderEntryButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
: ConstraintLayout(context, attrs, defStyleAttr) {

@BindView(R.id.reminder_entry_button_icon)
lateinit var icon: ImageView

@BindView(R.id.reminder_entry_button)
lateinit var button: Button

private var listener: OnClickListener? = null

init {
val view = LayoutInflater.from(context).inflate(R.layout.view_reminder_entry_button, this)
ButterKnife.bind(this, view)

attrs?.let {
val ta = context.obtainStyledAttributes(attrs, R.styleable.ReminderEntryButton)
val text = ta.getString(R.styleable.ReminderEntryButton_button_text)
val icon = ta.getResourceId(R.styleable.ReminderEntryButton_button_icon, 0)

if (icon > 0) {
setIcon(icon)
}

text?.let { setText(it) }

ta.recycle()
}
}

fun setText(text: String) {
this.button.text = text
}

fun setText(res: Int) {
setText(context.getString(res))
}

fun setIcon(@DrawableRes icon: Int) {
this.icon.setImageResource(icon)
}

override fun setOnClickListener(l: OnClickListener?) {
listener = l
}

@OnClick(R.id.reminder_entry_button, R.id.reminder_entry_button_icon)
protected fun onButtonClicked(view: View) {
listener?.onClick(view)
}
}
Loading

0 comments on commit 14190d7

Please sign in to comment.