mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-07-21 19:24:15 +00:00
Merge pull request #5482 from Alys/startDate-fix-2015-06-25
Refactor api.shouldDo and fix https://github.com/HabitRPG/habitrpg/issues/5395
This commit is contained in:
commit
eceae75631
4 changed files with 33 additions and 30 deletions
|
|
@ -1922,7 +1922,7 @@ api.subscriptionBlocks =
|
|||
basic_12mo: months:12, price:48
|
||||
_.each api.subscriptionBlocks, (b,k)->b.key = k
|
||||
|
||||
repeat = {m:true,t:true,w:true,th:true,f:true,s:true,su:true}
|
||||
# repeat = {m:true,t:true,w:true,th:true,f:true,s:true,su:true}
|
||||
api.userDefaults =
|
||||
habits: [
|
||||
{type: 'habit', text: t('defaultHabit1Text'), value: 0, up: true, down: false, attribute: 'per' }
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ api.startOfWeek = api.startOfWeek = (options={}) ->
|
|||
moment(o.now).startOf('week')
|
||||
|
||||
api.startOfDay = (options={}) ->
|
||||
# This is designed for use with any date that has an important time portion (e.g., when comparing the current date-time with the previous cron's date-time for determing if cron should run now).
|
||||
# It changes the time portion of the date-time to be the Custom Day Start hour, so that the date-time is now the user's correct start of day.
|
||||
# It SUBTRACTS a day if the date-time's original hour is before CDS (e.g., if your CDS is 5am and it's currently 4am, it's still the previous day).
|
||||
# This is NOT suitable for manipulating any dates that are displayed to the user as a date with no time portion, such as a Daily's Start Dates (e.g., a Start Date of today shows only the date, so it should be considered to be today even if the hidden time portion is before CDS).
|
||||
o = sanitizeOptions(options)
|
||||
dayStart = moment(o.now).startOf('day').add({hours:o.dayStart})
|
||||
if moment(o.now).hour() < o.dayStart
|
||||
|
|
@ -75,35 +79,34 @@ api.daysSince = (yesterday, options = {}) ->
|
|||
Should the user do this task on this date, given the task's repeat options and user.preferences.dayStart?
|
||||
###
|
||||
api.shouldDo = (day, dailyTask, options = {}) ->
|
||||
return false unless dailyTask.type == 'daily' && dailyTask.repeat
|
||||
if !dailyTask.startDate
|
||||
dailyTask.startDate = moment().toDate()
|
||||
if dailyTask.startDate instanceof String
|
||||
dailyTask.startDate = moment(dailyTask.startDate).toDate()
|
||||
return false unless dailyTask.type == 'daily'
|
||||
o = sanitizeOptions options
|
||||
day = api.startOfDay(_.defaults {now:day}, o)
|
||||
dayOfWeekNum = day.day() # e.g. 1 for Monday if week starts on Mon
|
||||
startOfDayWithCDSTime = api.startOfDay(_.defaults {now:day}, o) # a moment()
|
||||
|
||||
# check if event is today or in the future
|
||||
hasStartedCheck = day >= api.startOfDay(_.defaults {now:dailyTask.startDate}, o)
|
||||
# Work out if the Daily's Start Date (taskStartDate) is in the future.
|
||||
# The time portion of the Start Date is never visible to or modifiable by the user so we must ignore it.
|
||||
# Therefore, we must also ignore the time portion of the user's day start (startOfDayWithCDSTime), otherwise the date comparison will be wrong for some times.
|
||||
# NB: The user's day start date has already been converted to the PREVIOUS day's date if the time portion was before CDS.
|
||||
taskStartDate = moment(dailyTask.startDate || now()).startOf('day');
|
||||
if taskStartDate > startOfDayWithCDSTime.startOf('day')
|
||||
return false # Daily starts in the future
|
||||
|
||||
if dailyTask.frequency == 'daily'
|
||||
daysSinceTaskStart = api.numDaysApart(day.startOf('day'), dailyTask.startDate, o)
|
||||
if dailyTask.frequency == 'daily' # "Every X Days"
|
||||
if !dailyTask.everyX
|
||||
return false # error condition
|
||||
daysSinceTaskStart = startOfDayWithCDSTime.startOf('day').diff(taskStartDate, 'days')
|
||||
everyXCheck = (daysSinceTaskStart % dailyTask.everyX == 0)
|
||||
return everyXCheck && hasStartedCheck
|
||||
else if dailyTask.frequency == 'weekly'
|
||||
return everyXCheck
|
||||
else if dailyTask.frequency == 'weekly' # "On Certain Days of the Week"
|
||||
if !dailyTask.repeat
|
||||
return false # error condition
|
||||
dayOfWeekNum = startOfDayWithCDSTime.day() # e.g. 0 for Sunday
|
||||
dayOfWeekCheck = dailyTask.repeat[api.dayMapping[dayOfWeekNum]]
|
||||
return dayOfWeekCheck && hasStartedCheck
|
||||
return dayOfWeekCheck
|
||||
else
|
||||
# unexpected frequency string
|
||||
return false
|
||||
|
||||
api.numDaysApart = (day1, day2, o) ->
|
||||
startOfDay1 = api.startOfDay(_.defaults {now:day1}, o)
|
||||
startOfDay2 = api.startOfDay(_.defaults {now:day2}, o)
|
||||
numDays = Math.abs(startOfDay1.diff(startOfDay2, 'days'))
|
||||
return numDays
|
||||
|
||||
###
|
||||
------------------------------------------------------
|
||||
Level cap
|
||||
|
|
@ -235,7 +238,7 @@ api.taskDefaults = (task={}) ->
|
|||
_.defaults(task, {up:true,down:true}) if task.type is 'habit'
|
||||
_.defaults(task, {history: []}) if task.type in ['habit', 'daily']
|
||||
_.defaults(task, {completed:false}) if task.type in ['daily', 'todo']
|
||||
_.defaults(task, {streak:0, repeat: {su:1,m:1,t:1,w:1,th:1,f:1,s:1}}, startDate: new Date(), everyX: 1, frequency: 'weekly') if task.type is 'daily'
|
||||
_.defaults(task, {streak:0, repeat: {su:true,m:true,t:true,w:true,th:true,f:true,s:true}}, startDate: new Date(), everyX: 1, frequency: 'weekly') if task.type is 'daily'
|
||||
task._id = task.id # may need this for TaskSchema if we go back to using it, see http://goo.gl/a5irq4
|
||||
task.value ?= if task.type is 'reward' then 10 else 0
|
||||
task.priority = 1 unless _.isNumber(task.priority) # hotfix for apiv1. once we're off apiv1, we can remove this
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ cycle = (array)->
|
|||
return array[n % array.length]
|
||||
|
||||
repeatWithoutLastWeekday = ()->
|
||||
repeat = {su:1,m:1,t:1,w:1,th:1,f:1,s:1}
|
||||
repeat = {su:true,m:true,t:true,w:true,th:true,f:true,s:true}
|
||||
if shared.startOfWeek(moment().zone(0)).isoWeekday() == 1 # Monday
|
||||
repeat.su = false
|
||||
else
|
||||
|
|
@ -178,7 +178,7 @@ describe 'User', ->
|
|||
|
||||
# Handle greyed-out dailys
|
||||
yesterday = moment().subtract(1,'days')
|
||||
user.dailys[0].repeat[shared.dayMapping[yesterday.day()]] = 0
|
||||
user.dailys[0].repeat[shared.dayMapping[yesterday.day()]] = false
|
||||
_.each user.dailys[1..], (d)->d.completed = true
|
||||
cron()
|
||||
expect(user.stats.buffs.str).to.be 1
|
||||
|
|
@ -251,7 +251,7 @@ describe 'User', ->
|
|||
|
||||
it 'does not reset checklist on grey incomplete dailies', ->
|
||||
yesterday = moment().subtract(1,'days')
|
||||
user.dailys[0].repeat[shared.dayMapping[yesterday.day()]] = 0
|
||||
user.dailys[0].repeat[shared.dayMapping[yesterday.day()]] = false
|
||||
user.dailys[0].checklist = [
|
||||
{
|
||||
"text" : "1",
|
||||
|
|
@ -276,7 +276,7 @@ describe 'User', ->
|
|||
|
||||
it 'resets checklist on complete grey complete dailies', ->
|
||||
yesterday = moment().subtract(1,'days')
|
||||
user.dailys[0].repeat[shared.dayMapping[yesterday.day()]] = 0
|
||||
user.dailys[0].repeat[shared.dayMapping[yesterday.day()]] = false
|
||||
user.dailys[0].checklist = [
|
||||
{
|
||||
"text" : "1",
|
||||
|
|
@ -905,7 +905,7 @@ describe 'Cron', ->
|
|||
|
||||
'due today':
|
||||
# NOTE: a strange thing here, moment().startOf('week') is Sunday, but moment.zone(myTimeZone).startOf('week') is Monday.
|
||||
defaults: {repeat:{su:1,m:true,t:1,w:1,th:1,f:1,s:1}}
|
||||
defaults: {repeat:{su:true,m:true,t:true,w:true,th:true,f:true,s:true}}
|
||||
steps:
|
||||
'pre-dayStart':
|
||||
defaults: {currentHour:3, dayStart:4, shouldDo:true}
|
||||
|
|
@ -919,7 +919,7 @@ describe 'Cron', ->
|
|||
'unchecked': {checked:false, expect: 'losePoints'}
|
||||
|
||||
'NOT due today':
|
||||
defaults: {repeat:{su:1,m:false,t:1,w:1,th:1,f:1,s:1}}
|
||||
defaults: {repeat:{su:true,m:false,t:true,w:true,th:true,f:true,s:true}}
|
||||
steps:
|
||||
'pre-dayStart':
|
||||
defaults: {currentHour:3, dayStart:4, shouldDo:true}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ shared = require '../../common/script/index.coffee'
|
|||
shared.i18n.translations = require('../../website/src/i18n.js').translations
|
||||
|
||||
repeatWithoutLastWeekday = ()->
|
||||
repeat = {su:1,m:1,t:1,w:1,th:1,f:1,s:1}
|
||||
repeat = {su:true,m:true,t:true,w:true,th:true,f:true,s:true}
|
||||
if shared.startOfWeek(moment().zone(0)).isoWeekday() == 1 # Monday
|
||||
repeat.su = false
|
||||
else
|
||||
|
|
@ -64,7 +64,7 @@ describe 'daily/weekly that repeats everyday (default)', ->
|
|||
user = newUser()
|
||||
user.dailys = [
|
||||
shared.taskDefaults({type:'daily', startDate: moment().add(7, 'days'), frequency: 'daily'})
|
||||
shared.taskDefaults({type:'daily', startDate: moment().add(7, 'days'), frequency: 'weekly', repeat: {su:1,m:1,t:1,w:1,th:1,f:1,s:1}})
|
||||
shared.taskDefaults({type:'daily', startDate: moment().add(7, 'days'), frequency: 'weekly', repeat: {su:true,m:true,t:true,w:true,th:true,f:true,s:true}})
|
||||
]
|
||||
daily = user.dailys[0]
|
||||
weekly = user.dailys[1]
|
||||
|
|
|
|||
Loading…
Reference in a new issue