skydoves / Only

:bouquet: An easy way to persist and run code block only as many times as necessary on Android.
Apache License 2.0
483 stars 29 forks source link

[FR] Set a time period along with the number of times to do an action #3

Open ubarua123 opened 4 years ago

ubarua123 commented 4 years ago

Is your feature request related to a problem?

So the thing is, say I want to show a feedback dialog to the user every 2 months and do this for a certain number of times.

Describe the solution you'd like:

Set a time period and number of times the dialog should appear.

Time period = value in duration Count = number

You can even set exponential backoff for that. Like for example, first 3 counts, it asks every 3 months (the developer sets this time period parameter of course), then once the count is reached, it'll ask every 6 months and so on. Now with de-sugaring, you can incorporate java 8 time libraries for that.

skydoves commented 4 years ago

Hi, @ubarua123! Thank you for your issue, and this feature looks very useful. I will consider the implementation soon. Thank you for your issue 👍

yasiralijaved commented 3 years ago

@skydoves Is there update on this feature? I am also looking for the same feature. Thanks.

yasiralijaved commented 3 years ago

by the way, I have managed to achieve this functionality using "mark" feature. If the solution can be available using existing "Only" like style (builder pattern) then it would look more readable and understandable. Below is the code:

only("FeedbackDialogShownCount", 5) {
        onDo {

                doYourTask()

                // Update the last shown date-time
                Only.mark("FeedbackDialogShownCount", "${System.currentTimeMillis()}")
        }
        onDone{      // this block will be executed every time after the 5 times repetition of "onDo()"

                doYourTaskOnDone()

                val previousTimeInMillis = marking.toLong()
                val daysPassed = previousTimeInMillis.durationInDays(System.currentTimeMillis())
                if(daysPassed >= 31) {

                        doYourTaskOnce31DaysHasBeenPassed()

                        // Clear this "Only" target
                        Only.clearOnly("FeedbackDialogShownCount")
                        // Init the "Only" target from 1
                        Only.setOnlyTimes("FeedbackDialogShownCount", 1)
                        // Set the last shown as current date-time
                        Only.mark("FeedbackDialogShownCount", "${System.currentTimeMillis()}")
                }
        }
}

Here is the extension function durationInDays() which you can put in any kotlin class/file:

fun Long.durationInDays(endTimeMillis: Long): Int {
    //milliseconds
    val different: Long = endTimeMillis - this // "this" is start Time and endTimeMillis is end Time
    val secondsInMilli: Long = 1000
    val minutesInMilli = secondsInMilli * 60
    val hoursInMilli = minutesInMilli * 60
    val daysInMilli = hoursInMilli * 24

    val elapsedDays = different / daysInMilli

    return elapsedDays.toInt()
}
skydoves commented 3 years ago

Kotlin 1.4 introduced kotlin.time, so I will think about more this feature using the time.

onDo(refreshDuration = TimeUnit, refreshRules = OnlyRefreshRules.CLEAR (or OnlyRefreshRules.NOTHING)) {
  // do something..
}
ubarua123 commented 3 years ago

Any update on this feature? Thanks in advance!