mirror of
https://github.com/FossifyOrg/Clock.git
synced 2026-01-31 02:51:11 -05:00
resolve of PR
This commit is contained in:
@@ -13,7 +13,10 @@ import org.fossify.clock.BuildConfig
|
||||
import org.fossify.clock.R
|
||||
import org.fossify.clock.adapters.ViewPagerAdapter
|
||||
import org.fossify.clock.databinding.ActivityMainBinding
|
||||
import org.fossify.clock.extensions.*
|
||||
import org.fossify.clock.extensions.config
|
||||
import org.fossify.clock.extensions.getEnabledAlarms
|
||||
import org.fossify.clock.extensions.rescheduleEnabledAlarms
|
||||
import org.fossify.clock.extensions.updateWidgets
|
||||
import org.fossify.clock.helpers.*
|
||||
import org.fossify.commons.databinding.BottomTablayoutItemBinding
|
||||
import org.fossify.commons.extensions.*
|
||||
@@ -127,7 +130,11 @@ class MainActivity : SimpleActivity() {
|
||||
private fun setupOptionsMenu() {
|
||||
binding.mainToolbar.setOnMenuItemClickListener { menuItem ->
|
||||
when (menuItem.itemId) {
|
||||
R.id.sort -> getViewPagerAdapter()?.showAlarmSortDialog()
|
||||
R.id.sort -> when (binding.viewPager.currentItem) {
|
||||
TAB_ALARM_INDEX -> getViewPagerAdapter()?.showAlarmSortDialog()
|
||||
TAB_TIMER_INDEX -> getViewPagerAdapter()?.showTimerSortDialog()
|
||||
}
|
||||
|
||||
R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
|
||||
R.id.settings -> launchSettings()
|
||||
R.id.about -> launchAbout()
|
||||
@@ -139,7 +146,7 @@ class MainActivity : SimpleActivity() {
|
||||
|
||||
private fun refreshMenuItems() {
|
||||
binding.mainToolbar.menu.apply {
|
||||
findItem(R.id.sort).isVisible = binding.viewPager.currentItem == getTabIndex(TAB_ALARM)
|
||||
findItem(R.id.sort).isVisible = binding.viewPager.currentItem == getTabIndex(TAB_ALARM) || binding.viewPager.currentItem == getTabIndex(TAB_TIMER)
|
||||
findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(org.fossify.commons.R.bool.hide_google_relations)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package org.fossify.clock.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.Menu
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.fossify.clock.R
|
||||
import org.fossify.clock.activities.SimpleActivity
|
||||
import org.fossify.clock.databinding.ItemAlarmBinding
|
||||
@@ -14,17 +18,32 @@ import org.fossify.clock.interfaces.ToggleAlarmInterface
|
||||
import org.fossify.clock.models.Alarm
|
||||
import org.fossify.commons.adapters.MyRecyclerViewAdapter
|
||||
import org.fossify.commons.dialogs.ConfirmationDialog
|
||||
import org.fossify.commons.extensions.applyColorFilter
|
||||
import org.fossify.commons.extensions.beVisibleIf
|
||||
import org.fossify.commons.extensions.toast
|
||||
import org.fossify.commons.helpers.SORT_BY_CUSTOM
|
||||
import org.fossify.commons.interfaces.ItemMoveCallback
|
||||
import org.fossify.commons.interfaces.ItemTouchHelperContract
|
||||
import org.fossify.commons.interfaces.StartReorderDragListener
|
||||
import org.fossify.commons.views.MyRecyclerView
|
||||
|
||||
class AlarmsAdapter(
|
||||
activity: SimpleActivity, var alarms: ArrayList<Alarm>, val toggleAlarmInterface: ToggleAlarmInterface,
|
||||
recyclerView: MyRecyclerView, itemClick: (Any) -> Unit,
|
||||
) : MyRecyclerViewAdapter(activity, recyclerView, itemClick) {
|
||||
) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), ItemTouchHelperContract {
|
||||
|
||||
private var startReorderDragListener: StartReorderDragListener
|
||||
|
||||
init {
|
||||
setupDragListener(true)
|
||||
val touchHelper = ItemTouchHelper(ItemMoveCallback(this))
|
||||
touchHelper.attachToRecyclerView(recyclerView)
|
||||
|
||||
startReorderDragListener = object : StartReorderDragListener {
|
||||
override fun requestDrag(viewHolder: RecyclerView.ViewHolder) {
|
||||
touchHelper.startDrag(viewHolder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getActionMenuId() = R.menu.cab_alarms
|
||||
@@ -49,9 +68,19 @@ class AlarmsAdapter(
|
||||
|
||||
override fun getItemKeyPosition(key: Int) = alarms.indexOfFirst { it.id == key }
|
||||
|
||||
override fun onActionModeCreated() {}
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onActionModeCreated() {
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onActionModeDestroyed() {}
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onActionModeDestroyed() {
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onRowClear(myViewHolder: ViewHolder?) {}
|
||||
|
||||
override fun onRowSelected(myViewHolder: ViewHolder?) {}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
return createViewHolder(ItemAlarmBinding.inflate(layoutInflater, parent, false).root)
|
||||
@@ -59,14 +88,15 @@ class AlarmsAdapter(
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val alarm = alarms[position]
|
||||
holder.bindView(alarm, true, true) { itemView, layoutPosition ->
|
||||
setupView(itemView, alarm)
|
||||
holder.bindView(alarm, true, true) { itemView, _ ->
|
||||
setupView(itemView, alarm, holder)
|
||||
}
|
||||
bindViewHolder(holder)
|
||||
}
|
||||
|
||||
override fun getItemCount() = alarms.size
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun updateItems(newItems: ArrayList<Alarm>) {
|
||||
alarms = newItems
|
||||
notifyDataSetChanged()
|
||||
@@ -87,10 +117,19 @@ class AlarmsAdapter(
|
||||
|
||||
private fun getSelectedItems() = alarms.filter { selectedKeys.contains(it.id) } as ArrayList<Alarm>
|
||||
|
||||
private fun setupView(view: View, alarm: Alarm) {
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun setupView(view: View, alarm: Alarm, holder: ViewHolder) {
|
||||
val isSelected = selectedKeys.contains(alarm.id)
|
||||
ItemAlarmBinding.bind(view).apply {
|
||||
alarmHolder.isSelected = isSelected
|
||||
alarmDragHandle.beVisibleIf(selectedKeys.isNotEmpty())
|
||||
alarmDragHandle.applyColorFilter(textColor)
|
||||
alarmDragHandle.setOnTouchListener { _, event ->
|
||||
if (event.action == MotionEvent.ACTION_DOWN) {
|
||||
startReorderDragListener.requestDrag(holder)
|
||||
}
|
||||
false
|
||||
}
|
||||
alarmTime.text = activity.getFormattedTime(alarm.timeInMinutes * 60, false, true)
|
||||
alarmTime.setTextColor(textColor)
|
||||
|
||||
@@ -137,4 +176,19 @@ class AlarmsAdapter(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRowMoved(fromPosition: Int, toPosition: Int) {
|
||||
alarms.swap(fromPosition, toPosition)
|
||||
notifyItemMoved(fromPosition, toPosition)
|
||||
saveAlarmsCustomOrder(alarms)
|
||||
if (activity.config.alarmSort != SORT_BY_CUSTOM) {
|
||||
activity.config.alarmSort = SORT_BY_CUSTOM
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveAlarmsCustomOrder(alarms: ArrayList<Alarm>) {
|
||||
val alarmsCustomSortingIds = alarms.map { it.id }
|
||||
|
||||
activity.config.alarmsCustomSorting = alarmsCustomSortingIds.joinToString { it.toString() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.fossify.clock.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -52,6 +53,7 @@ class StopwatchAdapter(activity: SimpleActivity, var laps: ArrayList<Lap>, recyc
|
||||
|
||||
override fun getItemCount() = laps.size
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun updateItems(newItems: ArrayList<Lap>) {
|
||||
lastLapId = 0
|
||||
laps = newItems.clone() as ArrayList<Lap>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.fossify.clock.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -67,12 +68,14 @@ class TimeZonesAdapter(activity: SimpleActivity, var timeZones: ArrayList<MyTime
|
||||
|
||||
override fun getItemCount() = timeZones.size
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun updateItems(newItems: ArrayList<MyTimeZone>) {
|
||||
timeZones = newItems
|
||||
notifyDataSetChanged()
|
||||
finishActMode()
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun updateTimes() {
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
@@ -1,22 +1,41 @@
|
||||
package org.fossify.clock.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.Menu
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import me.grantland.widget.AutofitHelper
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.fossify.clock.R
|
||||
import org.fossify.clock.activities.SimpleActivity
|
||||
import org.fossify.clock.databinding.ItemTimerBinding
|
||||
import org.fossify.clock.extensions.config
|
||||
import org.fossify.clock.extensions.getFormattedDuration
|
||||
import org.fossify.clock.extensions.hideTimerNotification
|
||||
import org.fossify.clock.extensions.secondsToMillis
|
||||
import org.fossify.clock.extensions.swap
|
||||
import org.fossify.clock.models.Timer
|
||||
import org.fossify.clock.models.TimerEvent
|
||||
import org.fossify.clock.models.TimerState
|
||||
import org.fossify.clock.models.TimerState.Finished
|
||||
import org.fossify.clock.models.TimerState.Idle
|
||||
import org.fossify.clock.models.TimerState.Paused
|
||||
import org.fossify.clock.models.TimerState.Running
|
||||
import org.fossify.commons.adapters.MyRecyclerViewAdapter
|
||||
import org.fossify.commons.adapters.MyRecyclerViewListAdapter
|
||||
import org.fossify.commons.dialogs.PermissionRequiredDialog
|
||||
import org.fossify.commons.extensions.*
|
||||
import org.fossify.commons.extensions.adjustAlpha
|
||||
import org.fossify.commons.extensions.applyColorFilter
|
||||
import org.fossify.commons.extensions.beInvisibleIf
|
||||
import org.fossify.commons.extensions.beVisibleIf
|
||||
import org.fossify.commons.extensions.getColoredDrawableWithColor
|
||||
import org.fossify.commons.extensions.getFormattedDuration
|
||||
import org.fossify.commons.extensions.openNotificationSettings
|
||||
import org.fossify.commons.helpers.SORT_BY_CUSTOM
|
||||
import org.fossify.commons.interfaces.ItemMoveCallback
|
||||
import org.fossify.commons.interfaces.ItemTouchHelperContract
|
||||
import org.fossify.commons.interfaces.StartReorderDragListener
|
||||
import org.fossify.commons.views.MyRecyclerView
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
@@ -25,7 +44,15 @@ class TimerAdapter(
|
||||
recyclerView: MyRecyclerView,
|
||||
onRefresh: () -> Unit,
|
||||
onItemClick: (Timer) -> Unit,
|
||||
) : MyRecyclerViewListAdapter<Timer>(simpleActivity, recyclerView, diffUtil, onItemClick, onRefresh) {
|
||||
) : MyRecyclerViewListAdapter<Timer>(
|
||||
activity = simpleActivity,
|
||||
recyclerView = recyclerView,
|
||||
diffUtil = diffUtil,
|
||||
itemClick = onItemClick,
|
||||
onRefresh = onRefresh
|
||||
), ItemTouchHelperContract {
|
||||
|
||||
private var startReorderDragListener: StartReorderDragListener
|
||||
|
||||
companion object {
|
||||
private val diffUtil = object : DiffUtil.ItemCallback<Timer>() {
|
||||
@@ -41,6 +68,32 @@ class TimerAdapter(
|
||||
|
||||
init {
|
||||
setupDragListener(true)
|
||||
setHasStableIds(true)
|
||||
|
||||
val touchHelper = ItemTouchHelper(ItemMoveCallback(this))
|
||||
touchHelper.attachToRecyclerView(recyclerView)
|
||||
startReorderDragListener = object : StartReorderDragListener {
|
||||
override fun requestDrag(viewHolder: RecyclerView.ViewHolder) {
|
||||
touchHelper.startDrag(viewHolder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return getItem(position).id!!.toLong()
|
||||
}
|
||||
|
||||
override fun submitList(list: MutableList<Timer>?, commitCallback: Runnable?) {
|
||||
val layoutManager = recyclerView.layoutManager!!
|
||||
val recyclerViewState = layoutManager.onSaveInstanceState()
|
||||
super.submitList(list) {
|
||||
layoutManager.onRestoreInstanceState(recyclerViewState)
|
||||
commitCallback?.run()
|
||||
}
|
||||
}
|
||||
|
||||
override fun submitList(list: MutableList<Timer>?) {
|
||||
submitList(list, null)
|
||||
}
|
||||
|
||||
override fun getActionMenuId() = R.menu.cab_alarms
|
||||
@@ -74,17 +127,31 @@ class TimerAdapter(
|
||||
return position
|
||||
}
|
||||
|
||||
override fun onActionModeCreated() {}
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onActionModeCreated() {
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onActionModeDestroyed() {}
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onActionModeDestroyed() {
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onRowClear(myViewHolder: MyRecyclerViewAdapter.ViewHolder?) {}
|
||||
|
||||
override fun onRowSelected(myViewHolder: MyRecyclerViewAdapter.ViewHolder?) {}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
return createViewHolder(ItemTimerBinding.inflate(layoutInflater, parent, false).root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bindView(getItem(position), true, true) { itemView, _ ->
|
||||
setupView(itemView, getItem(position))
|
||||
holder.bindView(
|
||||
item = getItem(position),
|
||||
allowSingleClick = true,
|
||||
allowLongClick = true
|
||||
) { itemView, _ ->
|
||||
setupView(view = itemView, timer = getItem(position), holder = holder)
|
||||
}
|
||||
bindViewHolder(holder)
|
||||
}
|
||||
@@ -98,22 +165,31 @@ class TimerAdapter(
|
||||
timersToRemove.forEach(::deleteTimer)
|
||||
}
|
||||
|
||||
private fun setupView(view: View, timer: Timer) {
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun setupView(view: View, timer: Timer, holder: ViewHolder) {
|
||||
ItemTimerBinding.bind(view).apply {
|
||||
val isSelected = selectedKeys.contains(timer.id)
|
||||
timerFrame.isSelected = isSelected
|
||||
timerDragHandle.beVisibleIf(selectedKeys.isNotEmpty())
|
||||
timerDragHandle.applyColorFilter(textColor)
|
||||
timerDragHandle.setOnTouchListener { _, event ->
|
||||
if (event.action == MotionEvent.ACTION_DOWN) {
|
||||
startReorderDragListener.requestDrag(holder)
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
timerLabel.setTextColor(textColor)
|
||||
timerLabel.setHintTextColor(textColor.adjustAlpha(0.7f))
|
||||
timerLabel.text = timer.label
|
||||
timerLabel.beVisibleIf(timer.label.isNotEmpty())
|
||||
|
||||
AutofitHelper.create(timerTime)
|
||||
timerTime.setTextColor(textColor)
|
||||
timerTime.text = when (timer.state) {
|
||||
is TimerState.Finished -> 0.getFormattedDuration()
|
||||
is TimerState.Idle -> timer.seconds.getFormattedDuration()
|
||||
is TimerState.Paused -> timer.state.tick.getFormattedDuration()
|
||||
is TimerState.Running -> timer.state.tick.getFormattedDuration()
|
||||
is Finished -> 0.getFormattedDuration()
|
||||
is Idle -> timer.seconds.getFormattedDuration()
|
||||
is Paused -> timer.state.tick.getFormattedDuration()
|
||||
is Running -> timer.state.tick.getFormattedDuration()
|
||||
}
|
||||
|
||||
timerReset.applyColorFilter(textColor)
|
||||
@@ -123,32 +199,52 @@ class TimerAdapter(
|
||||
|
||||
timerPlayPause.applyColorFilter(textColor)
|
||||
timerPlayPause.setOnClickListener {
|
||||
(activity as SimpleActivity).handleNotificationPermission { granted ->
|
||||
if (granted) {
|
||||
when (val state = timer.state) {
|
||||
is TimerState.Idle -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis))
|
||||
is TimerState.Paused -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, state.tick))
|
||||
is TimerState.Running -> EventBus.getDefault().post(TimerEvent.Pause(timer.id!!, state.tick))
|
||||
is TimerState.Finished -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis))
|
||||
}
|
||||
} else {
|
||||
PermissionRequiredDialog(
|
||||
activity,
|
||||
org.fossify.commons.R.string.allow_notifications_reminders,
|
||||
{ activity.openNotificationSettings() })
|
||||
}
|
||||
}
|
||||
toggleTimer(timer)
|
||||
}
|
||||
|
||||
val state = timer.state
|
||||
val resetPossible = state is TimerState.Running || state is TimerState.Paused || state is TimerState.Finished
|
||||
val resetPossible = state is Running || state is Paused || state is Finished
|
||||
timerReset.beInvisibleIf(!resetPossible)
|
||||
val drawableId = if (state is TimerState.Running) {
|
||||
org.fossify.commons.R.drawable.ic_pause_vector
|
||||
timerPlayPause.setImageDrawable(
|
||||
simpleActivity.resources.getColoredDrawableWithColor(
|
||||
drawableId = if (state is Running) {
|
||||
org.fossify.commons.R.drawable.ic_pause_vector
|
||||
} else {
|
||||
org.fossify.commons.R.drawable.ic_play_vector
|
||||
},
|
||||
color = textColor
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleTimer(timer: Timer) {
|
||||
(activity as SimpleActivity).handleNotificationPermission { granted ->
|
||||
if (granted) {
|
||||
when (val state = timer.state) {
|
||||
is Idle -> EventBus.getDefault().post(
|
||||
TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis)
|
||||
)
|
||||
|
||||
is Paused -> EventBus.getDefault().post(
|
||||
TimerEvent.Start(timer.id!!, state.tick)
|
||||
)
|
||||
|
||||
is Running -> EventBus.getDefault().post(
|
||||
TimerEvent.Pause(timer.id!!, state.tick)
|
||||
)
|
||||
|
||||
is Finished -> EventBus.getDefault().post(
|
||||
TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
org.fossify.commons.R.drawable.ic_play_vector
|
||||
PermissionRequiredDialog(
|
||||
activity = activity,
|
||||
textId = org.fossify.commons.R.string.allow_notifications_reminders,
|
||||
positiveActionCallback = { activity.openNotificationSettings() }
|
||||
)
|
||||
}
|
||||
timerPlayPause.setImageDrawable(simpleActivity.resources.getColoredDrawableWithColor(drawableId, textColor))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,4 +257,20 @@ class TimerAdapter(
|
||||
EventBus.getDefault().post(TimerEvent.Delete(timer.id!!))
|
||||
simpleActivity.hideTimerNotification(timer.id!!)
|
||||
}
|
||||
|
||||
override fun onRowMoved(fromPosition: Int, toPosition: Int) {
|
||||
val timers = currentList.toMutableList()
|
||||
timers.swap(fromPosition, toPosition)
|
||||
submitList(timers)
|
||||
saveAlarmsCustomOrder(ArrayList(timers))
|
||||
if (simpleActivity.config.timerSort != SORT_BY_CUSTOM) {
|
||||
simpleActivity.config.timerSort = SORT_BY_CUSTOM
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveAlarmsCustomOrder(alarms: ArrayList<Timer>) {
|
||||
val timersCustomSortingIds = alarms.map { it.id }
|
||||
simpleActivity.config.timersCustomSorting =
|
||||
timersCustomSortingIds.joinToString { it.toString() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,10 @@ class ViewPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
|
||||
(fragments[TAB_ALARM_INDEX] as? AlarmFragment)?.showSortingDialog()
|
||||
}
|
||||
|
||||
fun showTimerSortDialog() {
|
||||
(fragments[TAB_TIMER_INDEX] as? TimerFragment)?.showSortingDialog()
|
||||
}
|
||||
|
||||
fun updateClockTabAlarm() {
|
||||
(fragments[TAB_CLOCK_INDEX] as? ClockFragment)?.updateAlarm()
|
||||
}
|
||||
|
||||
@@ -9,12 +9,14 @@ import org.fossify.clock.helpers.SORT_BY_DATE_AND_TIME
|
||||
import org.fossify.commons.activities.BaseSimpleActivity
|
||||
import org.fossify.commons.extensions.getAlertDialogBuilder
|
||||
import org.fossify.commons.extensions.setupDialogStuff
|
||||
import org.fossify.commons.helpers.SORT_BY_CUSTOM
|
||||
|
||||
class ChangeAlarmSortDialog(val activity: BaseSimpleActivity, val callback: () -> Unit) {
|
||||
private val binding = DialogChangeAlarmSortBinding.inflate(activity.layoutInflater).apply {
|
||||
val activeRadioButton = when (activity.config.alarmSort) {
|
||||
SORT_BY_ALARM_TIME -> sortingDialogRadioAlarmTime
|
||||
SORT_BY_DATE_AND_TIME -> sortingDialogRadioDayAndTime
|
||||
SORT_BY_CUSTOM -> sortingDialogRadioCustom
|
||||
else -> sortingDialogRadioCreationOrder
|
||||
}
|
||||
activeRadioButton.isChecked = true
|
||||
@@ -33,6 +35,7 @@ class ChangeAlarmSortDialog(val activity: BaseSimpleActivity, val callback: () -
|
||||
val sort = when (binding.sortingDialogRadioSorting.checkedRadioButtonId) {
|
||||
R.id.sorting_dialog_radio_alarm_time -> SORT_BY_ALARM_TIME
|
||||
R.id.sorting_dialog_radio_day_and_time -> SORT_BY_DATE_AND_TIME
|
||||
R.id.sorting_dialog_radio_custom -> SORT_BY_CUSTOM
|
||||
else -> SORT_BY_CREATION_ORDER
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.fossify.clock.dialogs
|
||||
|
||||
import org.fossify.clock.R
|
||||
import org.fossify.clock.databinding.DialogChangeTimerSortBinding
|
||||
import org.fossify.clock.extensions.config
|
||||
import org.fossify.clock.helpers.SORT_BY_CREATION_ORDER
|
||||
import org.fossify.clock.helpers.SORT_BY_TIMER_DURATION
|
||||
import org.fossify.commons.activities.BaseSimpleActivity
|
||||
import org.fossify.commons.extensions.getAlertDialogBuilder
|
||||
import org.fossify.commons.extensions.setupDialogStuff
|
||||
import org.fossify.commons.helpers.SORT_BY_CUSTOM
|
||||
|
||||
class ChangeTimerSortDialog(val activity: BaseSimpleActivity, val callback: () -> Unit) {
|
||||
private val binding = DialogChangeTimerSortBinding.inflate(activity.layoutInflater).apply {
|
||||
val activeRadioButton = when (activity.config.timerSort) {
|
||||
SORT_BY_TIMER_DURATION -> sortingDialogRadioTimerDuration
|
||||
SORT_BY_CUSTOM -> sortingDialogRadioCustom
|
||||
else -> sortingDialogRadioCreationOrder
|
||||
}
|
||||
activeRadioButton.isChecked = true
|
||||
}
|
||||
|
||||
init {
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(org.fossify.commons.R.string.ok) { _, _ -> dialogConfirmed() }
|
||||
.setNegativeButton(org.fossify.commons.R.string.cancel, null)
|
||||
.apply {
|
||||
activity.setupDialogStuff(binding.root, this, org.fossify.commons.R.string.sort_by)
|
||||
}
|
||||
}
|
||||
|
||||
private fun dialogConfirmed() {
|
||||
val sort = when (binding.sortingDialogRadioSorting.checkedRadioButtonId) {
|
||||
R.id.sorting_dialog_radio_timer_duration -> SORT_BY_TIMER_DURATION
|
||||
R.id.sorting_dialog_radio_custom -> SORT_BY_CUSTOM
|
||||
else -> SORT_BY_CREATION_ORDER
|
||||
}
|
||||
|
||||
activity.config.timerSort = sort
|
||||
callback()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.fossify.clock.extensions
|
||||
|
||||
@Deprecated(
|
||||
message = "Use the `move` extension function from commons",
|
||||
replaceWith = ReplaceWith(
|
||||
expression = "this.move(index1, index2)",
|
||||
imports = ["org.fossify.commons.extensions.move"]
|
||||
)
|
||||
)
|
||||
fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
|
||||
this[index1] = this[index2].also {
|
||||
this[index2] = this[index1]
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import org.fossify.commons.extensions.getProperBackgroundColor
|
||||
import org.fossify.commons.extensions.getProperTextColor
|
||||
import org.fossify.commons.extensions.toast
|
||||
import org.fossify.commons.extensions.updateTextColors
|
||||
import org.fossify.commons.helpers.SORT_BY_CUSTOM
|
||||
import org.fossify.commons.helpers.SORT_BY_DATE_CREATED
|
||||
import org.fossify.commons.helpers.ensureBackgroundThread
|
||||
import org.fossify.commons.models.AlarmSound
|
||||
@@ -84,6 +85,25 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface {
|
||||
}.thenBy {
|
||||
it.timeInMinutes
|
||||
})
|
||||
|
||||
SORT_BY_CUSTOM -> {
|
||||
val customAlarmsSortOrderString = activity?.config?.alarmsCustomSorting
|
||||
if (customAlarmsSortOrderString == "") {
|
||||
alarms.sortBy { it.id }
|
||||
} else {
|
||||
val customAlarmsSortOrder: List<Int> = customAlarmsSortOrderString?.split(", ")?.map { it.toInt() }!!
|
||||
val alarmsIdValueMap = alarms.associateBy { it.id }
|
||||
|
||||
val sortedAlarms: ArrayList<Alarm> = ArrayList()
|
||||
customAlarmsSortOrder.map { id ->
|
||||
if (alarmsIdValueMap[id] != null) {
|
||||
sortedAlarms.add(alarmsIdValueMap[id] as Alarm)
|
||||
}
|
||||
}
|
||||
|
||||
alarms = (sortedAlarms + alarms.filter { it !in sortedAlarms }) as ArrayList<Alarm>
|
||||
}
|
||||
}
|
||||
}
|
||||
context?.getEnabledAlarms { enabledAlarms ->
|
||||
if (enabledAlarms.isNullOrEmpty()) {
|
||||
|
||||
@@ -10,24 +10,27 @@ import androidx.fragment.app.Fragment
|
||||
import org.fossify.clock.activities.SimpleActivity
|
||||
import org.fossify.clock.adapters.TimerAdapter
|
||||
import org.fossify.clock.databinding.FragmentTimerBinding
|
||||
import org.fossify.clock.dialogs.ChangeTimerSortDialog
|
||||
import org.fossify.clock.dialogs.EditTimerDialog
|
||||
import org.fossify.clock.extensions.config
|
||||
import org.fossify.clock.extensions.createNewTimer
|
||||
import org.fossify.clock.extensions.timerHelper
|
||||
import org.fossify.clock.helpers.DisabledItemChangeAnimator
|
||||
import org.fossify.clock.helpers.SORT_BY_TIMER_DURATION
|
||||
import org.fossify.clock.models.Timer
|
||||
import org.fossify.clock.models.TimerEvent
|
||||
import org.fossify.commons.extensions.getProperBackgroundColor
|
||||
import org.fossify.commons.extensions.getProperTextColor
|
||||
import org.fossify.commons.extensions.hideKeyboard
|
||||
import org.fossify.commons.extensions.updateTextColors
|
||||
import org.fossify.commons.helpers.SORT_BY_CUSTOM
|
||||
import org.fossify.commons.helpers.SORT_BY_DATE_CREATED
|
||||
import org.fossify.commons.models.AlarmSound
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
class TimerFragment : Fragment() {
|
||||
private val INVALID_POSITION = -1
|
||||
private lateinit var binding: FragmentTimerBinding
|
||||
private lateinit var timerAdapter: TimerAdapter
|
||||
private var timerPositionToScrollTo = INVALID_POSITION
|
||||
@@ -43,7 +46,11 @@ class TimerFragment : Fragment() {
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?,
|
||||
): View {
|
||||
binding = FragmentTimerBinding.inflate(inflater, container, false).apply {
|
||||
timersList.itemAnimator = DisabledItemChangeAnimator()
|
||||
timerAdd.setOnClickListener {
|
||||
@@ -73,7 +80,12 @@ class TimerFragment : Fragment() {
|
||||
timerAdapter.updateBackgroundColor(requireContext().getProperBackgroundColor())
|
||||
timerAdapter.updateTextColor(requireContext().getProperTextColor())
|
||||
} else {
|
||||
timerAdapter = TimerAdapter(requireActivity() as SimpleActivity, binding.timersList, ::refreshTimers, ::openEditTimer)
|
||||
timerAdapter = TimerAdapter(
|
||||
simpleActivity = requireActivity() as SimpleActivity,
|
||||
recyclerView = binding.timersList,
|
||||
onRefresh = ::refreshTimers,
|
||||
onItemClick = ::openEditTimer
|
||||
)
|
||||
binding.timersList.adapter = timerAdapter
|
||||
}
|
||||
}
|
||||
@@ -85,16 +97,67 @@ class TimerFragment : Fragment() {
|
||||
refreshTimers()
|
||||
}
|
||||
|
||||
private fun refreshTimers(scrollToLatest: Boolean = false) {
|
||||
fun showSortingDialog() {
|
||||
ChangeTimerSortDialog(activity as SimpleActivity) {
|
||||
refreshTimers(
|
||||
animate = false // disable sorting animations for now.
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSortedTimers(callback: (List<Timer>) -> Unit) {
|
||||
activity?.timerHelper?.getTimers { timers ->
|
||||
val sortedTimers = when (requireContext().config.timerSort) {
|
||||
SORT_BY_TIMER_DURATION -> timers.sortedBy { it.seconds }
|
||||
SORT_BY_DATE_CREATED -> timers.sortedBy { it.id }
|
||||
SORT_BY_CUSTOM -> {
|
||||
val customTimersSortOrderString = activity?.config?.timersCustomSorting
|
||||
if (customTimersSortOrderString == "") {
|
||||
timers.sortedBy { it.id }
|
||||
} else {
|
||||
val customTimersSortOrder =
|
||||
customTimersSortOrderString?.split(", ")?.map { it.toInt() }!!
|
||||
val timersIdValueMap = timers.associateBy { it.id }
|
||||
|
||||
val sortedTimers: ArrayList<Timer> = ArrayList()
|
||||
customTimersSortOrder.map { id ->
|
||||
if (timersIdValueMap[id] != null) {
|
||||
sortedTimers.add(timersIdValueMap[id] as Timer)
|
||||
}
|
||||
}
|
||||
|
||||
(sortedTimers + timers.filter { it !in sortedTimers }) as ArrayList<Timer>
|
||||
}
|
||||
}
|
||||
|
||||
else -> timers
|
||||
}
|
||||
|
||||
activity?.runOnUiThread {
|
||||
timerAdapter.submitList(timers) {
|
||||
callback(sortedTimers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshTimers(animate: Boolean = true) {
|
||||
getSortedTimers { timers ->
|
||||
with(binding.timersList) {
|
||||
val originalAnimator = itemAnimator
|
||||
if (!animate) {
|
||||
itemAnimator = null
|
||||
}
|
||||
|
||||
timerAdapter.submitList(timers.toMutableList()) {
|
||||
view?.post {
|
||||
if (timerPositionToScrollTo != INVALID_POSITION && timerAdapter.itemCount > timerPositionToScrollTo) {
|
||||
binding.timersList.scrollToPosition(timerPositionToScrollTo)
|
||||
if (timerPositionToScrollTo != INVALID_POSITION &&
|
||||
timerAdapter.itemCount > timerPositionToScrollTo
|
||||
) {
|
||||
smoothScrollToPosition(timerPositionToScrollTo)
|
||||
timerPositionToScrollTo = INVALID_POSITION
|
||||
} else if (scrollToLatest) {
|
||||
binding.timersList.scrollToPosition(timers.lastIndex)
|
||||
}
|
||||
|
||||
if (!animate) {
|
||||
itemAnimator = originalAnimator
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,15 +175,13 @@ class TimerFragment : Fragment() {
|
||||
}
|
||||
|
||||
fun updatePosition(timerId: Int) {
|
||||
activity?.timerHelper?.getTimers { timers ->
|
||||
getSortedTimers { timers ->
|
||||
val position = timers.indexOfFirst { it.id == timerId }
|
||||
if (position != INVALID_POSITION) {
|
||||
activity?.runOnUiThread {
|
||||
if (timerAdapter.itemCount > position) {
|
||||
binding.timersList.scrollToPosition(position)
|
||||
} else {
|
||||
timerPositionToScrollTo = position
|
||||
}
|
||||
if (timerAdapter.itemCount > position) {
|
||||
binding.timersList.smoothScrollToPosition(position)
|
||||
} else {
|
||||
timerPositionToScrollTo = position
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,3 +194,5 @@ class TimerFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val INVALID_POSITION = -1
|
||||
|
||||
@@ -59,6 +59,18 @@ class Config(context: Context) : BaseConfig(context) {
|
||||
get() = prefs.getInt(ALARMS_SORT_BY, SORT_BY_CREATION_ORDER)
|
||||
set(alarmSort) = prefs.edit().putInt(ALARMS_SORT_BY, alarmSort).apply()
|
||||
|
||||
var alarmsCustomSorting: String
|
||||
get() = prefs.getString(ALARMS_CUSTOM_SORTING, "")!!
|
||||
set(alarmsCustomSorting) = prefs.edit().putString(ALARMS_CUSTOM_SORTING, alarmsCustomSorting).apply()
|
||||
|
||||
var timerSort: Int
|
||||
get() = prefs.getInt(TIMERS_SORT_BY, SORT_BY_CREATION_ORDER)
|
||||
set(timerSort) = prefs.edit().putInt(TIMERS_SORT_BY, timerSort).apply()
|
||||
|
||||
var timersCustomSorting: String
|
||||
get() = prefs.getString(TIMERS_CUSTOM_SORTING, "")!!
|
||||
set(timersCustomSorting) = prefs.edit().putString(TIMERS_CUSTOM_SORTING, timersCustomSorting).apply()
|
||||
|
||||
var alarmMaxReminderSecs: Int
|
||||
get() = prefs.getInt(ALARM_MAX_REMINDER_SECS, DEFAULT_MAX_ALARM_REMINDER_SECS)
|
||||
set(alarmMaxReminderSecs) = prefs.edit().putInt(ALARM_MAX_REMINDER_SECS, alarmMaxReminderSecs).apply()
|
||||
|
||||
@@ -24,6 +24,9 @@ const val ALARM_LAST_CONFIG = "alarm_last_config"
|
||||
const val TIMER_LAST_CONFIG = "timer_last_config"
|
||||
const val INCREASE_VOLUME_GRADUALLY = "increase_volume_gradually"
|
||||
const val ALARMS_SORT_BY = "alarms_sort_by"
|
||||
const val ALARMS_CUSTOM_SORTING = "alarms_custom_sorting"
|
||||
const val TIMERS_SORT_BY = "timers_sort_by"
|
||||
const val TIMERS_CUSTOM_SORTING = "timers_custom_sorting"
|
||||
const val STOPWATCH_LAPS_SORT_BY = "stopwatch_laps_sort_by"
|
||||
const val WAS_INITIAL_WIDGET_SET_UP = "was_initial_widget_set_up"
|
||||
const val DATA_EXPORT_EXTENSION = ".json"
|
||||
@@ -70,10 +73,11 @@ const val SORT_BY_LAP = 1
|
||||
const val SORT_BY_LAP_TIME = 2
|
||||
const val SORT_BY_TOTAL_TIME = 4
|
||||
|
||||
// alarm sorting
|
||||
// alarm and timer sorting
|
||||
const val SORT_BY_CREATION_ORDER = 0
|
||||
const val SORT_BY_ALARM_TIME = 1
|
||||
const val SORT_BY_DATE_AND_TIME = 2
|
||||
const val SORT_BY_TIMER_DURATION = 3
|
||||
|
||||
const val TODAY_BIT = -1
|
||||
const val TOMORROW_BIT = -2
|
||||
@@ -188,6 +192,7 @@ fun getAllTimeZones() = arrayListOf(
|
||||
MyTimeZone(28, "GMT-01:00 Cape Verde", "Atlantic/Cape_Verde"),
|
||||
MyTimeZone(29, "GMT+00:00 Casablanca", "Africa/Casablanca"),
|
||||
MyTimeZone(30, "GMT+00:00 Greenwich Mean Time", "Etc/Greenwich"),
|
||||
MyTimeZone(90, "GMT+00:00 London", "Europe/London"),
|
||||
MyTimeZone(31, "GMT+01:00 Amsterdam", "Europe/Amsterdam"),
|
||||
MyTimeZone(32, "GMT+01:00 Belgrade", "Europe/Belgrade"),
|
||||
MyTimeZone(33, "GMT+01:00 Brussels", "Europe/Brussels"),
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.fossify.clock.views
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
/**
|
||||
* A simple wrapper TextView that restores the original text size
|
||||
* when view width is restored.
|
||||
*/
|
||||
@SuppressLint("AppCompatCustomView")
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
class AutoFitTextView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyle: Int = 0,
|
||||
) : TextView(context, attrs, defStyle) {
|
||||
|
||||
private var originalTextSize: Float = textSize
|
||||
private var originalWidth: Int = 0
|
||||
|
||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||
if (originalWidth == 0) {
|
||||
originalWidth = w
|
||||
}
|
||||
|
||||
post {
|
||||
if (w >= originalWidth && textSize != originalTextSize) {
|
||||
disableAutoSizing()
|
||||
setTextSize(TypedValue.COMPLEX_UNIT_PX, originalTextSize)
|
||||
enableAutoSizing()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun disableAutoSizing() {
|
||||
setAutoSizeTextTypeWithDefaults(AUTO_SIZE_TEXT_TYPE_NONE)
|
||||
}
|
||||
|
||||
private fun enableAutoSizing() {
|
||||
post { setAutoSizeTextTypeWithDefaults(AUTO_SIZE_TEXT_TYPE_UNIFORM) }
|
||||
}
|
||||
}
|
||||
@@ -37,5 +37,13 @@
|
||||
android:paddingBottom="@dimen/medium_margin"
|
||||
android:text="@string/sort_by_day_and_alarm_time" />
|
||||
|
||||
<org.fossify.commons.views.MyCompatRadioButton
|
||||
android:id="@+id/sorting_dialog_radio_custom"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/medium_margin"
|
||||
android:paddingBottom="@dimen/medium_margin"
|
||||
android:text="@string/custom" />
|
||||
|
||||
</RadioGroup>
|
||||
</ScrollView>
|
||||
|
||||
41
app/src/main/res/layout/dialog_change_timer_sort.xml
Normal file
41
app/src/main/res/layout/dialog_change_timer_sort.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/sorting_dialog_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/sorting_dialog_radio_sorting"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/medium_margin"
|
||||
android:paddingStart="@dimen/activity_margin"
|
||||
android:paddingTop="@dimen/activity_margin"
|
||||
android:paddingEnd="@dimen/activity_margin">
|
||||
|
||||
<org.fossify.commons.views.MyCompatRadioButton
|
||||
android:id="@+id/sorting_dialog_radio_creation_order"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/medium_margin"
|
||||
android:paddingBottom="@dimen/medium_margin"
|
||||
android:text="@string/sort_by_creation_order" />
|
||||
|
||||
<org.fossify.commons.views.MyCompatRadioButton
|
||||
android:id="@+id/sorting_dialog_radio_timer_duration"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/medium_margin"
|
||||
android:paddingBottom="@dimen/medium_margin"
|
||||
android:text="@string/sort_by_timer_duration" />
|
||||
|
||||
<org.fossify.commons.views.MyCompatRadioButton
|
||||
android:id="@+id/sorting_dialog_radio_custom"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/medium_margin"
|
||||
android:paddingBottom="@dimen/medium_margin"
|
||||
android:text="@string/custom" />
|
||||
|
||||
</RadioGroup>
|
||||
</ScrollView>
|
||||
@@ -59,7 +59,20 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="@dimen/normal_margin"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/alarm_drag_handle"
|
||||
app:layout_constraintStart_toEndOf="@id/alarm_time"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/alarm_drag_handle"
|
||||
android:layout_width="@dimen/drag_handle_size"
|
||||
android:layout_height="@dimen/drag_handle_size"
|
||||
android:paddingHorizontal="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_drag_handle_vector"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/alarm_switch"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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/timer_frame"
|
||||
@@ -8,70 +8,83 @@
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="@drawable/selector">
|
||||
android:foreground="@drawable/selector"
|
||||
android:paddingHorizontal="@dimen/activity_margin"
|
||||
android:paddingVertical="@dimen/normal_margin">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
<org.fossify.clock.views.AutoFitTextView
|
||||
android:id="@+id/timer_time"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/activity_margin"
|
||||
android:paddingTop="@dimen/medium_margin"
|
||||
android:paddingBottom="@dimen/activity_margin">
|
||||
android:autoSizeMaxTextSize="@dimen/timer_text_size"
|
||||
android:autoSizeMinTextSize="@dimen/extra_big_text_size"
|
||||
android:autoSizeStepGranularity="2sp"
|
||||
android:autoSizeTextType="uniform"
|
||||
android:gravity="center_vertical"
|
||||
android:includeFontPadding="false"
|
||||
android:maxLines="1"
|
||||
android:textSize="@dimen/timer_text_size"
|
||||
app:layout_constraintBottom_toTopOf="@id/timer_label"
|
||||
app:layout_constraintEnd_toStartOf="@id/timer_reset"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="01:30:00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timer_time"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:includeFontPadding="false"
|
||||
android:maxLines="1"
|
||||
android:textSize="@dimen/alarm_text_size"
|
||||
app:layout_constraintEnd_toStartOf="@id/timer_reset"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="00:00" />
|
||||
<org.fossify.commons.views.MyTextView
|
||||
android:id="@+id/timer_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:includeFontPadding="false"
|
||||
android:maxLines="1"
|
||||
android:textSize="@dimen/bigger_text_size"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@id/timer_time"
|
||||
app:layout_constraintStart_toStartOf="@id/timer_time"
|
||||
app:layout_constraintTop_toBottomOf="@id/timer_time"
|
||||
tools:text="Siesta 🥱💤"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<org.fossify.commons.views.MyTextView
|
||||
android:id="@+id/timer_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:includeFontPadding="false"
|
||||
android:maxLines="1"
|
||||
android:textSize="@dimen/bigger_text_size"
|
||||
app:layout_constraintEnd_toEndOf="@id/timer_time"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/timer_time"
|
||||
tools:text="Cook rice" />
|
||||
<ImageView
|
||||
android:id="@+id/timer_reset"
|
||||
android:layout_width="@dimen/timer_button_small_size"
|
||||
android:layout_height="@dimen/timer_button_small_size"
|
||||
android:layout_marginHorizontal="@dimen/medium_margin"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="@dimen/normal_margin"
|
||||
android:src="@drawable/ic_reset_vector"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/timer_play_pause"
|
||||
app:layout_constraintStart_toEndOf="@id/timer_time"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/timer_reset"
|
||||
android:layout_width="@dimen/timer_button_small_size"
|
||||
android:layout_height="@dimen/timer_button_small_size"
|
||||
android:layout_marginStart="@dimen/medium_margin"
|
||||
android:layout_marginEnd="@dimen/medium_margin"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="@dimen/normal_margin"
|
||||
android:src="@drawable/ic_reset_vector"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/timer_play_pause"
|
||||
app:layout_constraintEnd_toStartOf="@+id/timer_play_pause"
|
||||
app:layout_constraintStart_toEndOf="@id/timer_time"
|
||||
app:layout_constraintTop_toTopOf="@id/timer_play_pause" />
|
||||
<ImageView
|
||||
android:id="@+id/timer_play_pause"
|
||||
android:layout_width="@dimen/timer_button_size"
|
||||
android:layout_height="@dimen/timer_button_size"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="@dimen/activity_margin"
|
||||
android:src="@drawable/ic_play_vector"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/timer_drag_handle"
|
||||
app:layout_constraintStart_toEndOf="@id/timer_reset"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/timer_play_pause"
|
||||
android:layout_width="@dimen/timer_button_size"
|
||||
android:layout_height="@dimen/timer_button_size"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginStart="@dimen/medium_margin"
|
||||
android:layout_marginEnd="@dimen/small_margin"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="@dimen/activity_margin"
|
||||
android:src="@drawable/ic_play_vector"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/timer_reset"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<ImageView
|
||||
android:id="@+id/timer_drag_handle"
|
||||
android:layout_width="@dimen/drag_handle_size"
|
||||
android:layout_height="@dimen/drag_handle_size"
|
||||
android:layout_marginStart="@dimen/medium_margin"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_drag_handle_vector"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/timer_play_pause"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</FrameLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
<dimen name="timer_button_small_size">50dp</dimen>
|
||||
<dimen name="timer_button_size">56dp</dimen>
|
||||
<dimen name="textview_drawable_size">24dp</dimen>
|
||||
<dimen name="drag_handle_size">40dp</dimen>
|
||||
|
||||
<dimen name="clock_text_size">70sp</dimen>
|
||||
<dimen name="clock_text_size_smaller">60sp</dimen>
|
||||
<dimen name="alarm_text_size">60sp</dimen>
|
||||
<dimen name="timer_text_size">@dimen/alarm_text_size</dimen>
|
||||
<dimen name="stopwatch_text_size">80sp</dimen>
|
||||
<dimen name="widget_time_text_size_small">48sp</dimen>
|
||||
<dimen name="widget_details_text_size">14sp</dimen>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<string name="swipe_right_to_dismiss">Swipe right to Dismiss, or left to Snooze.</string>
|
||||
<string name="sort_by_creation_order">Creation order</string>
|
||||
<string name="sort_by_alarm_time">Alarm time</string>
|
||||
<string name="sort_by_timer_duration">Timer duration</string>
|
||||
<string name="sort_by_day_and_alarm_time">Day and Alarm time</string>
|
||||
<string name="analogue_clock">Analogue clock</string>
|
||||
<string name="digital_clock">Digital clock</string>
|
||||
|
||||
Reference in New Issue
Block a user