This commit is contained in:
Pavol Franek 2020-03-08 10:47:42 +01:00
parent c3ab1f9330
commit ed18715b39
4 changed files with 98 additions and 80 deletions

View File

@ -10,7 +10,6 @@ import android.media.AudioManager
import android.os.Build
import android.os.Bundle
import android.os.CountDownTimer
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -26,10 +25,7 @@ import com.simplemobiletools.clock.extensions.*
import com.simplemobiletools.clock.helpers.Config
import com.simplemobiletools.clock.helpers.PICK_AUDIO_FILE_INTENT_ID
import com.simplemobiletools.clock.helpers.TIMER_NOTIF_ID
import com.simplemobiletools.clock.workers.TIMER_WORKER_KEY
import com.simplemobiletools.clock.workers.cancelTimerWorker
import com.simplemobiletools.clock.workers.enqueueTimerWorker
import com.simplemobiletools.clock.workers.timerRequestId
import com.simplemobiletools.clock.workers.*
import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ALARM_SOUND_TYPE_ALARM
@ -38,24 +34,53 @@ import com.simplemobiletools.commons.models.AlarmSound
import kotlinx.android.synthetic.main.fragment_timer.view.*
import java.util.concurrent.TimeUnit
class TimerFragment : Fragment() {
lateinit var view: ViewGroup
private var timer: CountDownTimer? = null
private var isRunning = false
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val config = requiredActivity.config
view = (inflater.inflate(R.layout.fragment_timer, container, false) as ViewGroup).apply {
val config = requiredActivity.config
val textColor = config.textColor
requiredActivity.updateTextColors(timer_fragment)
timer_play_pause.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, context!!.getAdjustedPrimaryColor())
timer_reset.applyColorFilter(textColor)
timer_initial_time.text = config.timerSeconds.getFormattedDuration()
timer_initial_time.colorLeftDrawable(textColor)
timer_vibrate.isChecked = config.timerVibrate
timer_vibrate.colorLeftDrawable(textColor)
timer_sound.text = config.timerSoundTitle
timer_sound.colorLeftDrawable(textColor)
timer_time.setOnClickListener {
startTimer(config)
if (isRunning) {
pauseTimer(config)
} else {
startTimer(config)
}
}
timer_play_pause.setOnClickListener {
startTimer(config)
if (isRunning) {
pauseTimer(config)
} else {
startTimer(config)
}
}
timer_reset.setOnClickListener {
cancelTimerWorker()
requiredActivity.hideTimerNotification()
config.timerTickStamp = 0L
config.timerStartStamp = 0L
requiredActivity.toast(R.string.timer_stopped)
}
@ -63,7 +88,6 @@ class TimerFragment : Fragment() {
MyTimePickerDialogDialog(activity as SimpleActivity, config.timerSeconds) { seconds ->
val timerSeconds = if (seconds <= 0) 10 else seconds
config.timerSeconds = timerSeconds
config.timerTimeStamp = System.currentTimeMillis() + timerSeconds
timer_initial_time.text = timerSeconds.getFormattedDuration()
}
}
@ -92,15 +116,20 @@ class TimerFragment : Fragment() {
}
WorkManager.getInstance(requiredActivity).getWorkInfosByTagLiveData(TIMER_WORKER_KEY).observe(requiredActivity, Observer { workInfo ->
workInfo.log("log")
val workerState = workInfo?.firstOrNull()?.state
isRunning = (workerState == WorkInfo.State.ENQUEUED)
updateIcons(isRunning)
timer_reset.beVisibleIf(isRunning)
timer?.cancel()
when (workerState) {
WorkInfo.State.ENQUEUED -> {
timer?.cancel()
timer = object : CountDownTimer(config.timerSeconds.toLong().times(1000), 1000) {
val duration = config.timerSeconds.toLong() * 1000 //MS
timer = object : CountDownTimer(duration, 1000) {
override fun onTick(millisUntilFinished: Long) {
timer_time.text = millisUntilFinished.div(1000).toInt().getFormattedDuration()
timer_time.text = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished).toInt().getFormattedDuration()
}
override fun onFinish() {}
@ -111,34 +140,46 @@ class TimerFragment : Fragment() {
timer_time.text = 0.getFormattedDuration()
}
}
updateIcons(workerState == WorkInfo.State.ENQUEUED)
timer_reset.beVisibleIf(workerState == WorkInfo.State.ENQUEUED)
})
cancelTimerWorker()
}
return view
}
private fun startTimer(config: Config) {
val selectedDuration = config.timerSeconds
val formattedTimestamp = config.timerTimeStamp.timestampFormat("HH:mm:ss")
enqueueTimerWorker(TimeUnit.SECONDS.toMillis(selectedDuration.toLong()))
showNotification("(${selectedDuration.getFormattedDuration()}) $formattedTimestamp")
val isTimerNoTick = config.timerTickStamp == 0L
if (isTimerNoTick) {
config.timerStartStamp = System.currentTimeMillis()
val selectedDuration = config.timerSeconds
val formattedTimestamp = config.timerStartStamp.timestampFormat("HH:mm:ss")
enqueueTimerWorker(TimeUnit.SECONDS.toMillis(selectedDuration.toLong()))
showNotification("(${selectedDuration.getFormattedDuration()}) $formattedTimestamp")
} else {
val duration = config.timerSeconds.toLong() * 1000 //MS
val selectedDuration = (config.timerStartStamp + duration) - (config.timerTickStamp - config.timerStartStamp)
val formattedTimestamp = config.timerStartStamp.timestampFormat("HH:mm:ss")
enqueueTimerWorker(TimeUnit.SECONDS.toMillis(selectedDuration.toLong()))
showNotification("(${selectedDuration.toInt().getFormattedDuration()}) $formattedTimestamp")
}
}
override fun onResume() {
super.onResume()
setupViews()
}
private fun pauseTimer(config: Config) {
cancelTimerWorker()
requiredActivity.hideTimerNotification()
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState.apply {})
}
config.timerTickStamp = System.currentTimeMillis()
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
savedInstanceState?.apply {}
val tick = config.timerTickStamp
val duration = config.timerSeconds.toLong() * 1000 //MS
val startedAt = config.timerStartStamp
val distance = duration - (tick - startedAt)
view.timer_time.text = distance.toInt().getFormattedDuration()
}
fun updateAlarmSound(alarmSound: AlarmSound) {
@ -147,30 +188,6 @@ class TimerFragment : Fragment() {
view.timer_sound.text = alarmSound.title
}
// private val isRunning
// get(): Boolean =
// WorkManager.getInstance(requiredActivity).getWorkInfosByTagLiveData(TIMER_WORKER_KEY).value?.firstOrNull()?.state == WorkInfo.State.ENQUEUED
private fun setupViews() {
val config = requiredActivity.config
val textColor = config.textColor
view.apply {
requiredActivity.updateTextColors(timer_fragment)
timer_play_pause.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, context!!.getAdjustedPrimaryColor())
timer_reset.applyColorFilter(textColor)
timer_initial_time.text = config.timerSeconds.getFormattedDuration()
timer_initial_time.colorLeftDrawable(textColor)
timer_vibrate.isChecked = config.timerVibrate
timer_vibrate.colorLeftDrawable(textColor)
timer_sound.text = config.timerSoundTitle
timer_sound.colorLeftDrawable(textColor)
}
}
private fun updateIcons(isRunning: Boolean) {
val drawableId = if (isRunning) R.drawable.ic_pause_vector else R.drawable.ic_play_vector
val iconColor = if (requiredActivity.getAdjustedPrimaryColor() == Color.WHITE) Color.BLACK else requiredActivity.config.textColor

View File

@ -5,7 +5,6 @@ import com.simplemobiletools.commons.extensions.getDefaultAlarmTitle
import com.simplemobiletools.commons.extensions.getDefaultAlarmUri
import com.simplemobiletools.commons.helpers.ALARM_SOUND_TYPE_ALARM
import com.simplemobiletools.commons.helpers.BaseConfig
import java.util.concurrent.TimeUnit
class Config(context: Context) : BaseConfig(context) {
companion object {
@ -28,9 +27,13 @@ class Config(context: Context) : BaseConfig(context) {
get() = prefs.getInt(TIMER_SECONDS, 300)
set(lastTimerSeconds) = prefs.edit().putInt(TIMER_SECONDS, lastTimerSeconds).apply()
var timerTimeStamp: Long
get() = prefs.getLong(TIMER_TIMESTAMP, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(timerSeconds.toLong()))
set(timestamp) = prefs.edit().putLong(TIMER_TIMESTAMP, timestamp).apply()
var timerStartStamp: Long
get() = prefs.getLong(TIMER_START_TIMESTAMP, 0L)
set(timestamp) = prefs.edit().putLong(TIMER_START_TIMESTAMP, timestamp).apply()
var timerTickStamp: Long
get() = prefs.getLong(TIMER_TICK_TIMESTAMP, 0L)
set(timestamp) = prefs.edit().putLong(TIMER_TICK_TIMESTAMP, timestamp).apply()
var timerVibrate: Boolean
get() = prefs.getBoolean(TIMER_VIBRATE, false)

View File

@ -8,7 +8,8 @@ const val SHOW_SECONDS = "show_seconds"
const val SELECTED_TIME_ZONES = "selected_time_zones"
const val EDITED_TIME_ZONE_TITLES = "edited_time_zone_titles"
const val TIMER_SECONDS = "timer_seconds"
const val TIMER_TIMESTAMP = "timer_timetamp"
const val TIMER_START_TIMESTAMP = "timer_timetamp"
const val TIMER_TICK_TIMESTAMP = "timer_tick"
const val TIMER_VIBRATE = "timer_vibrate"
const val TIMER_SOUND_URI = "timer_sound_uri"
const val TIMER_SOUND_TITLE = "timer_sound_title"

View File

@ -11,34 +11,31 @@ private const val TIMER_REQUEST_ID = "TIMER_REQUEST_ID"
const val TIMER_WORKER_KEY = "TIMER_WORKER_KEY"
private fun Fragment.saveTimerRequestId(uuid: UUID) =
preferences.edit().putString(TIMER_REQUEST_ID, uuid.toString()).apply()
preferences.edit().putString(TIMER_REQUEST_ID, uuid.toString()).apply()
val Fragment.timerRequestId: UUID? get() =
preferences.getString(TIMER_REQUEST_ID, UUID.randomUUID().toString())?.let { UUID.fromString(it) }
val Fragment.timerRequestId: UUID?
get() =
preferences.getString(TIMER_REQUEST_ID, UUID.randomUUID().toString())?.let { UUID.fromString(it) }
fun Fragment.cancelTimerWorker() =
WorkManager.getInstance(requiredActivity).cancelAllWorkByTag(TIMER_WORKER_KEY)
WorkManager.getInstance(requiredActivity).cancelAllWorkByTag(TIMER_WORKER_KEY)
fun Fragment.enqueueTimerWorker(delay: Long) =
WorkManager.getInstance(requiredActivity).enqueueUniqueWork(TIMER_WORKER_KEY, ExistingWorkPolicy.REPLACE, timerRequest(delay))
WorkManager.getInstance(requiredActivity).enqueueUniqueWork(TIMER_WORKER_KEY, ExistingWorkPolicy.REPLACE, timerRequest(delay))
private fun Fragment.timerRequest(delay: Long) =
OneTimeWorkRequestBuilder<TimerWorker>().setInitialDelay(delay, TimeUnit.MILLISECONDS).addTag(TIMER_WORKER_KEY).build().also {
private fun Fragment.timerRequest(delay: Long): OneTimeWorkRequest =
OneTimeWorkRequestBuilder<TimerWorker>().setInitialDelay(delay, TimeUnit.MILLISECONDS).addTag(TIMER_WORKER_KEY).build().also {
saveTimerRequestId(it.id)
}
}
class TimerWorker(val context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result =
try {
context.showTimerNotification(false)
Result.success()
} catch (exception: Exception) {
Result.failure()
}
override fun onStopped() {
super.onStopped()
context.hideTimerNotification()
}
try {
context.showTimerNotification(false)
context.config.timerTickStamp = 0L
context.config.timerStartStamp = 0L
Result.success()
} catch (exception: Exception) {
Result.failure()
}
}