Merge branch 'develop' into nthomsn-develop
2
.gitignore
vendored
|
|
@ -27,4 +27,4 @@ coverage
|
|||
coverage.html
|
||||
common/dist/scripts/habitrpg-shared.js
|
||||
|
||||
test/spec/translations.js
|
||||
test/spec/mocks/translations.js
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ module.exports = function(grunt) {
|
|||
require('coffee-script');
|
||||
var i18n = require('./website/src/i18n'),
|
||||
fs = require('fs');
|
||||
fs.writeFileSync('test/spec/translations.js',
|
||||
fs.writeFileSync('test/spec/mocks/translations.js',
|
||||
"if(!window.env) window.env = {};\n" +
|
||||
"window.env.translations = " + JSON.stringify(i18n.translations['en']) + ';');
|
||||
});
|
||||
|
|
|
|||
BIN
common/dist/sprites/spritesmith2.png
vendored
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 697 B After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 664 B After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 705 B After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 693 B After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 667 B After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 542 B After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 3.2 KiB |
|
|
@ -48,5 +48,9 @@
|
|||
"removeTasks": "Remove Tasks",
|
||||
"keepTasks": "Keep Tasks",
|
||||
"closeCha": "Close challenge and...",
|
||||
"leaveCha": "Leave challenge and..."
|
||||
"leaveCha": "Leave challenge and...",
|
||||
"challengedOwnedFilterHeader": "Ownership",
|
||||
"challengedOwnedFilter": "Owned",
|
||||
"challengedNotOwnedFilter": "Not Owned",
|
||||
"challengedEitherOwnedFilter": "Either"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@
|
|||
"newDailyBulk": "New Dailies (one per line)",
|
||||
"streakCounter": "Streak Counter",
|
||||
"repeat": "Repeat",
|
||||
"repeatEvery": "Repeat Every",
|
||||
"repeatDays": "Every X Days",
|
||||
"repeatWeek": "On Certain Days of the Week",
|
||||
"day": "Day",
|
||||
"days": "Days",
|
||||
"restoreStreak": "Restore Streak",
|
||||
"todos": "To-Dos",
|
||||
"newTodo": "New To-Do",
|
||||
|
|
@ -60,6 +65,9 @@
|
|||
"clearTags": "Clear",
|
||||
"hideTags": "Hide",
|
||||
"showTags": "Show",
|
||||
"startDate": "Start Date",
|
||||
"startDateHelpTitle": "When should this task start?",
|
||||
"startDateHelp": "Set the date for which this task takes effect. Will not be due on earlier days.",
|
||||
"streakName": "Streak Achievements",
|
||||
"streakText": "Has performed <%= streaks %> 21-day streaks on Dailies",
|
||||
"streakSingular": "Streaker",
|
||||
|
|
@ -95,5 +103,6 @@
|
|||
"rewardHelp1": "The Equipment you buy for your avatar is stored in <%= linkStart %>Inventory > Equipment<%= linkEnd %>.",
|
||||
"rewardHelp2": "Equipment affects your stats (<%= linkStart %>Avatar > Stats<%= linkEnd %>).",
|
||||
"rewardHelp3": "Special equipment will appear here during World Events.",
|
||||
"rewardHelp4": "Don't be afraid to set custom Rewards! Check out <a href='http://habitrpg.wikia.com/wiki/Sample_Custom_Rewards' target='_blank'>some samples here</a>."
|
||||
"rewardHelp4": "Don't be afraid to set custom Rewards! Check out <a href='http://habitrpg.wikia.com/wiki/Sample_Custom_Rewards' target='_blank'>some samples here</a>.",
|
||||
"clickForHelp": "Click for help"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
"newReward": "New Reward",
|
||||
"newRewardBulk": "New Rewards (one per line)",
|
||||
"price": "Price",
|
||||
"search": "Search",
|
||||
"tags": "Tags",
|
||||
"editTags": "Edit",
|
||||
"newTag": "New Tag",
|
||||
|
|
@ -79,4 +80,4 @@
|
|||
"pushTaskToBottom": "Push task to bottom",
|
||||
"emptyTask": "Enter the task's title first.",
|
||||
"dailiesRestingInInn": "You're Resting in the Inn! Your Dailies will NOT hurt you tonight, but they WILL still refresh every day. If you're in a quest, you won't deal damage/collect items until you check out of the Inn, but you can still be injured by a Boss if your Party mates skip their own Dailies."
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,13 +72,37 @@ api.daysSince = (yesterday, options = {}) ->
|
|||
Math.abs api.startOfDay(_.defaults {now:yesterday}, o).diff(api.startOfDay(_.defaults {now:o.now}, o), 'days')
|
||||
|
||||
###
|
||||
Should the user do this taks on this date, given the task's repeat options and user.preferences.dayStart?
|
||||
Should the user do this task on this date, given the task's repeat options and user.preferences.dayStart?
|
||||
###
|
||||
api.shouldDo = (day, repeat, options={}) ->
|
||||
return false unless repeat
|
||||
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()
|
||||
o = sanitizeOptions options
|
||||
selected = repeat[api.dayMapping[api.startOfDay(_.defaults {now:day}, o).day()]]
|
||||
return selected
|
||||
day = api.startOfDay(_.defaults {now:day}, o)
|
||||
dayOfWeekNum = day.day() # e.g. 1 for Monday if week starts on Mon
|
||||
|
||||
# check if event is today or in the future
|
||||
hasStartedCheck = day >= api.startOfDay(_.defaults {now:dailyTask.startDate}, o)
|
||||
|
||||
if dailyTask.frequency == 'daily'
|
||||
daysSinceTaskStart = api.numDaysApart(day.startOf('day'), dailyTask.startDate, o)
|
||||
everyXCheck = (daysSinceTaskStart % dailyTask.everyX == 0)
|
||||
return everyXCheck && hasStartedCheck
|
||||
else if dailyTask.frequency == 'weekly'
|
||||
dayOfWeekCheck = dailyTask.repeat[api.dayMapping[dayOfWeekNum]]
|
||||
return dayOfWeekCheck && hasStartedCheck
|
||||
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
|
||||
|
||||
###
|
||||
------------------------------------------------------
|
||||
|
|
@ -211,7 +235,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}}) if task.type is 'daily'
|
||||
_.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'
|
||||
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
|
||||
|
|
@ -281,7 +305,7 @@ api.taskClasses = (task, filters=[], dayStart=0, lastCron=+new Date, showComplet
|
|||
|
||||
# show as completed if completed (naturally) or not required for today
|
||||
if type in ['todo', 'daily']
|
||||
if completed or (type is 'daily' and !api.shouldDo(+new Date, task.repeat, {dayStart}))
|
||||
if completed or (type is 'daily' and !api.shouldDo(+new Date, task, {dayStart}))
|
||||
classes += " completed"
|
||||
else
|
||||
classes += " uncompleted"
|
||||
|
|
@ -534,7 +558,7 @@ api.wrap = (user, main=true) ->
|
|||
user.preferences.costume = false
|
||||
# Remove unlocked features
|
||||
flags = user.flags
|
||||
if not (user.achievements.ultimateGear or user.achievements.beastMaster)
|
||||
if not user.achievements.beastMaster
|
||||
flags.rebirthEnabled = false
|
||||
flags.itemsEnabled = false
|
||||
flags.dropsEnabled = false
|
||||
|
|
@ -1489,7 +1513,7 @@ api.wrap = (user, main=true) ->
|
|||
user._tmp.drop = _.defaults content.quests[k],
|
||||
type: 'Quest'
|
||||
dialog: i18n.t('messageFoundQuest', {questText: content.quests[k].text(req.language)}, req.language)
|
||||
if !user.flags.rebirthEnabled and (user.stats.lvl >= 50 or user.achievements.ultimateGear or user.achievements.beastMaster)
|
||||
if !user.flags.rebirthEnabled and (user.stats.lvl >= 50 or user.achievements.beastMaster)
|
||||
user.flags.rebirthEnabled = true
|
||||
if user.stats.lvl >= api.maxLevel and !user.flags.freeRebirth
|
||||
user.flags.freeRebirth = true
|
||||
|
|
@ -1565,7 +1589,7 @@ api.wrap = (user, main=true) ->
|
|||
{completed, repeat} = daily
|
||||
thatDay = moment(now).subtract({days: 1})
|
||||
|
||||
if api.shouldDo(thatDay, repeat, user.preferences) || completed
|
||||
if api.shouldDo(thatDay.toDate(), daily, user.preferences) || completed
|
||||
_.each daily.checklist, ((box)->box.completed=false;true)
|
||||
daily.completed = false
|
||||
return
|
||||
|
|
@ -1592,7 +1616,7 @@ api.wrap = (user, main=true) ->
|
|||
scheduleMisses = 0
|
||||
_.times daysMissed, (n) ->
|
||||
thatDay = moment(now).subtract({days: n + 1})
|
||||
if api.shouldDo(thatDay, repeat, user.preferences)
|
||||
if api.shouldDo(thatDay.toDate(), task, user.preferences)
|
||||
scheduleMisses++
|
||||
if user.stats.buffs.stealth
|
||||
user.stats.buffs.stealth--
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ module.exports = function(config) {
|
|||
'website/public/bower_components/js-emoji/emoji.js',
|
||||
'common/dist/scripts/habitrpg-shared.js',
|
||||
|
||||
"test/spec/translations.js",
|
||||
"test/spec/mocks/translations.js",
|
||||
|
||||
"website/public/js/env.js",
|
||||
|
||||
|
|
@ -51,7 +51,9 @@ module.exports = function(config) {
|
|||
"website/public/js/services/challengeServices.js",
|
||||
"website/public/js/services/paymentServices.js",
|
||||
|
||||
"website/public/js/filters/filters.js",
|
||||
"website/public/js/filters/money.js",
|
||||
"website/public/js/filters/roundLargeNumbers.js",
|
||||
"website/public/js/filters/taskOrdering.js",
|
||||
|
||||
"website/public/js/directives/focus-me.directive.js",
|
||||
"website/public/js/directives/from-now.directive.js",
|
||||
|
|
@ -77,7 +79,7 @@ module.exports = function(config) {
|
|||
"website/public/js/controllers/footerCtrl.js",
|
||||
"website/public/js/controllers/challengesCtrl.js",
|
||||
"website/public/js/controllers/hallCtrl.js",
|
||||
'test/spec/mock/**/*.js',
|
||||
'test/spec/mocks/**/*.js',
|
||||
'test/spec/specHelper.js',
|
||||
'test/spec/**/*.js'
|
||||
],
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ describe 'User', ->
|
|||
it 'handles perfect days', ->
|
||||
user = newUser()
|
||||
user.dailys = []
|
||||
_.times 3, ->user.dailys.push shared.taskDefaults({type:'daily'})
|
||||
_.times 3, ->user.dailys.push shared.taskDefaults({type:'daily', startDate: moment().subtract(7, 'days')})
|
||||
cron = -> user.lastCron = moment().subtract(1,'days');user.fns.cron()
|
||||
|
||||
cron()
|
||||
|
|
@ -193,7 +193,7 @@ describe 'User', ->
|
|||
user.preferences.sleep = true
|
||||
cron = -> user.lastCron = moment().subtract(1, 'days');user.fns.cron()
|
||||
user.dailys = []
|
||||
_.times 2, -> user.dailys.push shared.taskDefaults({type:'daily'})
|
||||
_.times 2, -> user.dailys.push shared.taskDefaults({type:'daily', startDate: moment().subtract(7, 'days')})
|
||||
|
||||
it 'remains in the inn on cron', ->
|
||||
cron()
|
||||
|
|
@ -883,8 +883,9 @@ describe 'Cron', ->
|
|||
before.dailys[0].repeat = after.dailys[0].repeat = options.repeat if options.repeat
|
||||
before.dailys[0].streak = after.dailys[0].streak = 10
|
||||
before.dailys[0].completed = after.dailys[0].completed = true if options.checked
|
||||
before.dailys[0].startDate = after.dailys[0].startDate = moment().subtract(30, 'days')
|
||||
if options.shouldDo
|
||||
expect(shared.shouldDo(now, options.repeat, {timezoneOffset, dayStart:options.dayStart, now})).to.be.ok()
|
||||
expect(shared.shouldDo(now.toDate(), after.dailys[0], {timezoneOffset, dayStart:options.dayStart, now})).to.be.ok()
|
||||
after.fns.cron {now}
|
||||
before.stats.mp=after.stats.mp #FIXME
|
||||
switch options.expect
|
||||
|
|
|
|||
330
test/common/dailies.coffee
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
_ = require 'lodash'
|
||||
expect = require 'expect.js'
|
||||
sinon = require 'sinon'
|
||||
moment = require 'moment'
|
||||
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}
|
||||
if shared.startOfWeek(moment().zone(0)).isoWeekday() == 1 # Monday
|
||||
repeat.su = false
|
||||
else
|
||||
repeat.s = false
|
||||
{repeat: repeat}
|
||||
|
||||
### Helper Functions ####
|
||||
# @TODO: Refactor into helper file
|
||||
newUser = (addTasks=true)->
|
||||
buffs = {per:0, int:0, con:0, str:0, stealth: 0, streaks: false}
|
||||
user =
|
||||
auth:
|
||||
timestamps: {}
|
||||
stats: {str:1, con:1, per:1, int:1, mp: 32, class: 'warrior', buffs: buffs}
|
||||
items:
|
||||
lastDrop:
|
||||
count: 0
|
||||
hatchingPotions: {}
|
||||
eggs: {}
|
||||
food: {}
|
||||
gear:
|
||||
equipped: {}
|
||||
costume: {}
|
||||
party:
|
||||
quest:
|
||||
progress:
|
||||
down: 0
|
||||
preferences: {}
|
||||
dailys: []
|
||||
todos: []
|
||||
rewards: []
|
||||
flags: {}
|
||||
achievements: {}
|
||||
contributor:
|
||||
level: 2
|
||||
shared.wrap(user)
|
||||
user.ops.reset(null, ->)
|
||||
if addTasks
|
||||
_.each ['habit', 'todo', 'daily'], (task)->
|
||||
user.ops.addTask {body: {type: task, id: shared.uuid()}}
|
||||
user
|
||||
|
||||
cron = (usr) ->
|
||||
usr.lastCron = moment().subtract(1,'days')
|
||||
usr.fns.cron()
|
||||
|
||||
describe 'daily/weekly that repeats everyday (default)', ->
|
||||
user = null
|
||||
daily = null
|
||||
weekly = null
|
||||
|
||||
describe 'when startDate is in the future', ->
|
||||
|
||||
beforeEach ->
|
||||
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}})
|
||||
]
|
||||
daily = user.dailys[0]
|
||||
weekly = user.dailys[1]
|
||||
|
||||
it 'does not damage user for not completing it', ->
|
||||
cron(user)
|
||||
expect(user.stats.hp).to.be 50
|
||||
|
||||
it 'does not change value on cron if daily is incomplete', ->
|
||||
cron(user)
|
||||
expect(daily.value).to.be 0
|
||||
expect(weekly.value).to.be 0
|
||||
|
||||
it 'does not reset checklists if daily is not marked as complete', ->
|
||||
checklist = [
|
||||
{
|
||||
'text' : '1',
|
||||
'id' : 'checklist-one',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '2',
|
||||
'id' : 'checklist-two',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '3',
|
||||
'id' : 'checklist-three',
|
||||
'completed' : false
|
||||
}
|
||||
]
|
||||
daily.checklist = checklist
|
||||
weekly.checklist = checklist
|
||||
cron(user)
|
||||
|
||||
expect(daily.checklist[0].completed).to.be true
|
||||
expect(daily.checklist[1].completed).to.be true
|
||||
expect(daily.checklist[2].completed).to.be false
|
||||
|
||||
expect(weekly.checklist[0].completed).to.be true
|
||||
expect(weekly.checklist[1].completed).to.be true
|
||||
expect(weekly.checklist[2].completed).to.be false
|
||||
|
||||
it 'resets checklists if daily is marked as complete', ->
|
||||
checklist = [
|
||||
{
|
||||
'text' : '1',
|
||||
'id' : 'checklist-one',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '2',
|
||||
'id' : 'checklist-two',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '3',
|
||||
'id' : 'checklist-three',
|
||||
'completed' : false
|
||||
}
|
||||
]
|
||||
daily.checklist = checklist
|
||||
weekly.checklist = checklist
|
||||
daily.completed = true
|
||||
weekly.completed = true
|
||||
cron(user)
|
||||
|
||||
_.each daily.checklist, (box)->
|
||||
expect(box.completed).to.be false
|
||||
|
||||
_.each weekly.checklist, (box)->
|
||||
expect(box.completed).to.be false
|
||||
|
||||
it 'is due on startDate', ->
|
||||
daily_due_today = shared.shouldDo moment(), daily
|
||||
daily_due_on_start_date = shared.shouldDo moment().add(7, 'days'), daily
|
||||
|
||||
expect(daily_due_today).to.be false
|
||||
expect(daily_due_on_start_date).to.be true
|
||||
|
||||
weekly_due_today = shared.shouldDo moment(), weekly
|
||||
weekly_due_on_start_date = shared.shouldDo moment().add(7, 'days'), weekly
|
||||
|
||||
expect(weekly_due_today).to.be false
|
||||
expect(weekly_due_on_start_date).to.be true
|
||||
|
||||
describe 'when startDate is in the past', ->
|
||||
completeDaily = null
|
||||
|
||||
beforeEach ->
|
||||
user = newUser()
|
||||
user.dailys = [
|
||||
shared.taskDefaults({type:'daily', startDate: moment().subtract(7, 'days'), frequency: 'daily'})
|
||||
shared.taskDefaults({type:'daily', startDate: moment().subtract(7, 'days'), frequency: 'weekly'})
|
||||
]
|
||||
daily = user.dailys[0]
|
||||
weekly = user.dailys[1]
|
||||
|
||||
it 'does damage user for not completing it', ->
|
||||
cron(user)
|
||||
expect(user.stats.hp).to.be.lessThan 50
|
||||
|
||||
it 'decreases value on cron if daily is incomplete', ->
|
||||
cron(user)
|
||||
expect(daily.value).to.be.lessThan 0
|
||||
expect(weekly.value).to.be.lessThan 0
|
||||
|
||||
it 'resets checklists if daily is not marked as complete', ->
|
||||
checklist = [
|
||||
{
|
||||
'text' : '1',
|
||||
'id' : 'checklist-one',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '2',
|
||||
'id' : 'checklist-two',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '3',
|
||||
'id' : 'checklist-three',
|
||||
'completed' : false
|
||||
}
|
||||
]
|
||||
daily.checklist = checklist
|
||||
weekly.checklist = checklist
|
||||
cron(user)
|
||||
|
||||
_.each daily.checklist, (box)->
|
||||
expect(box.completed).to.be false
|
||||
|
||||
_.each weekly.checklist, (box)->
|
||||
expect(box.completed).to.be false
|
||||
|
||||
it 'resets checklists if daily is marked as complete', ->
|
||||
checklist = [
|
||||
{
|
||||
'text' : '1',
|
||||
'id' : 'checklist-one',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '2',
|
||||
'id' : 'checklist-two',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '3',
|
||||
'id' : 'checklist-three',
|
||||
'completed' : false
|
||||
}
|
||||
]
|
||||
daily.checklist = checklist
|
||||
daily.completed = true
|
||||
weekly.checklist = checklist
|
||||
weekly.completed = true
|
||||
cron(user)
|
||||
|
||||
_.each daily.checklist, (box)->
|
||||
expect(box.completed).to.be false
|
||||
|
||||
_.each weekly.checklist, (box)->
|
||||
expect(box.completed).to.be false
|
||||
|
||||
describe 'when startDate is today', ->
|
||||
completeDaily = null
|
||||
|
||||
beforeEach ->
|
||||
user = newUser()
|
||||
user.dailys = [
|
||||
# Must set start date to yesterday, because cron mock sets last cron to yesterday
|
||||
shared.taskDefaults({type:'daily', startDate: moment().subtract(1, 'days'), frequency: 'daily'})
|
||||
shared.taskDefaults({type:'daily', startDate: moment().subtract(1, 'days'), frequency: 'weekly'})
|
||||
]
|
||||
daily = user.dailys[0]
|
||||
weekly = user.dailys[1]
|
||||
|
||||
it 'does damage user for not completing it', ->
|
||||
cron(user)
|
||||
expect(user.stats.hp).to.be.lessThan 50
|
||||
|
||||
it 'decreases value on cron if daily is incomplete', ->
|
||||
cron(user)
|
||||
expect(daily.value).to.be.lessThan 0
|
||||
expect(weekly.value).to.be.lessThan 0
|
||||
|
||||
it 'resets checklists if daily is not marked as complete', ->
|
||||
checklist = [
|
||||
{
|
||||
'text' : '1',
|
||||
'id' : 'checklist-one',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '2',
|
||||
'id' : 'checklist-two',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '3',
|
||||
'id' : 'checklist-three',
|
||||
'completed' : false
|
||||
}
|
||||
]
|
||||
daily.checklist = checklist
|
||||
weekly.checklist = checklist
|
||||
cron(user)
|
||||
|
||||
_.each daily.checklist, (box)->
|
||||
expect(box.completed).to.be false
|
||||
|
||||
_.each weekly.checklist, (box)->
|
||||
expect(box.completed).to.be false
|
||||
|
||||
it 'resets checklists if daily is marked as complete', ->
|
||||
checklist = [
|
||||
{
|
||||
'text' : '1',
|
||||
'id' : 'checklist-one',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '2',
|
||||
'id' : 'checklist-two',
|
||||
'completed' : true
|
||||
},
|
||||
{
|
||||
'text' : '3',
|
||||
'id' : 'checklist-three',
|
||||
'completed' : false
|
||||
}
|
||||
]
|
||||
daily.checklist = checklist
|
||||
daily.completed = true
|
||||
weekly.checklist = checklist
|
||||
weekly.completed = true
|
||||
cron(user)
|
||||
|
||||
_.each daily.checklist, (box)->
|
||||
expect(box.completed).to.be false
|
||||
|
||||
_.each weekly.checklist, (box)->
|
||||
expect(box.completed).to.be false
|
||||
|
||||
describe 'daily that repeats every x days', ->
|
||||
user = null
|
||||
daily = null
|
||||
|
||||
beforeEach ->
|
||||
user = newUser()
|
||||
user.dailys = [ shared.taskDefaults({type:'daily', startDate: moment(), frequency: 'daily'}) ]
|
||||
daily = user.dailys[0]
|
||||
|
||||
_.times 11, (due) ->
|
||||
|
||||
it 'where x equals ' + due, ->
|
||||
daily.everyX = due
|
||||
|
||||
_.times 30, (day) ->
|
||||
isDue = shared.shouldDo moment().add(day, 'days'), daily
|
||||
expect(isDue).to.be true if day % due == 0
|
||||
expect(isDue).to.be false if day % due != 0
|
||||
177
test/spec/controllers/challengesCtrlSpec.js
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
'use strict';
|
||||
|
||||
describe('Challenges Controller', function() {
|
||||
var $rootScope, scope, user, ctrl, challenges, groups;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('User', {});
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller, Challenges, Groups){
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id";
|
||||
|
||||
scope = $rootScope.$new();
|
||||
|
||||
// Load RootCtrl to ensure shared behaviors are loaded
|
||||
$controller('RootCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
ctrl = $controller('ChallengesCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
challenges = Challenges;
|
||||
groups = Groups;
|
||||
});
|
||||
});
|
||||
|
||||
describe('filterChallenges', function() {
|
||||
var ownMem, ownNotMem, notOwnMem, notOwnNotMem;
|
||||
|
||||
beforeEach(function() {
|
||||
ownMem = new challenges.Challenge({
|
||||
name: 'test',
|
||||
description: 'You are the owner and member',
|
||||
habits: [],
|
||||
dailys: [],
|
||||
todos: [],
|
||||
rewards: [],
|
||||
leader: user._id,
|
||||
group: "test",
|
||||
timestamp: +(new Date),
|
||||
members: [user],
|
||||
official: false,
|
||||
_isMember: true
|
||||
});
|
||||
|
||||
ownNotMem = new challenges.Challenge({
|
||||
name: 'test',
|
||||
description: 'You are the owner, but not a member',
|
||||
habits: [],
|
||||
dailys: [],
|
||||
todos: [],
|
||||
rewards: [],
|
||||
leader: user._id,
|
||||
group: "test",
|
||||
timestamp: +(new Date),
|
||||
members: [],
|
||||
official: false,
|
||||
_isMember: false
|
||||
});
|
||||
|
||||
notOwnMem = new challenges.Challenge({
|
||||
name: 'test',
|
||||
description: 'Not owner but a member',
|
||||
habits: [],
|
||||
dailys: [],
|
||||
todos: [],
|
||||
rewards: [],
|
||||
leader: {_id:"test"},
|
||||
group: "test",
|
||||
timestamp: +(new Date),
|
||||
members: [user],
|
||||
official: false,
|
||||
_isMember: true
|
||||
});
|
||||
|
||||
notOwnNotMem = new challenges.Challenge({
|
||||
name: 'test',
|
||||
description: 'Not owner or member',
|
||||
habits: [],
|
||||
dailys: [],
|
||||
todos: [],
|
||||
rewards: [],
|
||||
leader: {_id:"test"},
|
||||
group: "test",
|
||||
timestamp: +(new Date),
|
||||
members: [],
|
||||
official: false,
|
||||
_isMember: false
|
||||
});
|
||||
|
||||
scope.search = {
|
||||
group: _.transform(groups, function(m,g){m[g._id]=true;})
|
||||
};
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: either and owner: either', function() {
|
||||
scope.search._isMember = 'either';
|
||||
scope.search._isOwner = 'either';
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: either and owner: true', function() {
|
||||
scope.search._isMember = 'either';
|
||||
scope.search._isOwner = true;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: either and owner: false', function() {
|
||||
scope.search._isMember = 'either';
|
||||
scope.search._isOwner = false;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: true and owner: either', function() {
|
||||
scope.search._isMember = true;
|
||||
scope.search._isOwner = 'either';
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: true and owner: true', function() {
|
||||
scope.search._isMember = true;
|
||||
scope.search._isOwner = true;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: true and owner: false', function() {
|
||||
scope.search._isMember = true;
|
||||
scope.search._isOwner = false;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: false and owner: either', function() {
|
||||
scope.search._isMember = false;
|
||||
scope.search._isOwner = 'either';
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: false and owner: true', function() {
|
||||
scope.search._isMember = false;
|
||||
scope.search._isOwner = true;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
|
||||
});
|
||||
|
||||
it('displays challenges that match membership: false and owner: false', function() {
|
||||
scope.search._isMember = false;
|
||||
scope.search._isOwner = false;
|
||||
expect(scope.filterChallenges(ownMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
|
||||
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
39
test/spec/controllers/filtersCtrlSpec.js
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
describe('Filters Controller', function() {
|
||||
var scope, user;
|
||||
|
||||
beforeEach(inject(function($rootScope, $controller, Shared) {
|
||||
user = specHelper.newUser();
|
||||
Shared.wrap(user);
|
||||
scope = $rootScope.$new();
|
||||
$controller('FiltersCtrl', {$scope: scope, User: {user: user}});
|
||||
}));
|
||||
|
||||
describe('tags', function(){
|
||||
it('creates a tag', function(){
|
||||
scope._newTag = {name:'tagName'}
|
||||
scope.createTag();
|
||||
expect(user.tags).to.have.length(1);
|
||||
expect(user.tags[0].name).to.eql('tagName');
|
||||
expect(user.tags[0]).to.have.property('id');
|
||||
});
|
||||
|
||||
it('toggles tag filtering', inject(function(Shared){
|
||||
var tag = {id: Shared.uuid(), name: 'myTag'};
|
||||
scope.toggleFilter(tag);
|
||||
expect(user.filters[tag.id]).to.eql(true);
|
||||
scope.toggleFilter(tag);
|
||||
expect(user.filters[tag.id]).to.eql(false);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('updateTaskFilter', function(){
|
||||
it('updatest user\'s filter query with the value of filterQuery', function () {
|
||||
scope.filterQuery = 'task';
|
||||
scope.updateTaskFilter();
|
||||
|
||||
expect(user.filterQuery).to.eql(scope.filterQuery);
|
||||
});
|
||||
});
|
||||
});
|
||||
33
test/spec/filters/largeRoundNumbersSpec.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
describe('roundLargeNumbers', function() {
|
||||
|
||||
beforeEach(module('habitrpg'));
|
||||
|
||||
it('returns same number if less than 1000', inject(function(roundLargeNumbersFilter) {
|
||||
for(var num = 0; num < 1000; num++) {
|
||||
expect(roundLargeNumbersFilter(num)).to.eql(num);
|
||||
};
|
||||
}));
|
||||
|
||||
it('truncates number and appends "k" if number is 1000-999999', inject(function(roundLargeNumbersFilter) {
|
||||
expect(roundLargeNumbersFilter(999.01)).to.eql("1.0k");
|
||||
expect(roundLargeNumbersFilter(1000)).to.eql("1.0k");
|
||||
expect(roundLargeNumbersFilter(3284.12)).to.eql("3.3k");
|
||||
expect(roundLargeNumbersFilter(52983.99)).to.eql("53.0k");
|
||||
expect(roundLargeNumbersFilter(452983.99)).to.eql("453.0k");
|
||||
expect(roundLargeNumbersFilter(999999)).to.eql("1000.0k");
|
||||
}));
|
||||
|
||||
it('truncates number and appends "m" if number is 1000000-999999999', inject(function(roundLargeNumbersFilter) {
|
||||
expect(roundLargeNumbersFilter(999999.01)).to.eql("1.0m");
|
||||
expect(roundLargeNumbersFilter(1000000)).to.eql("1.0m");
|
||||
expect(roundLargeNumbersFilter(3284124.12)).to.eql("3.3m");
|
||||
expect(roundLargeNumbersFilter(52983105.99)).to.eql("53.0m");
|
||||
expect(roundLargeNumbersFilter(452983410.99)).to.eql("453.0m");
|
||||
expect(roundLargeNumbersFilter(999999999)).to.eql("1000.0m");
|
||||
}));
|
||||
|
||||
it('truncates number and appends b" if number is greater than 999999999', inject(function(roundLargeNumbersFilter) {
|
||||
expect(roundLargeNumbersFilter(999999999.01)).to.eql("1.0b");
|
||||
expect(roundLargeNumbersFilter(1423985738.54)).to.eql("1.4b");
|
||||
}));
|
||||
});
|
||||
35
test/spec/filters/moneySpec.js
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
describe('filter', function() {
|
||||
|
||||
beforeEach(module('habitrpg'));
|
||||
|
||||
describe('gold', function() {
|
||||
it('rounds down decimal values', inject(function(goldFilter) {
|
||||
expect(goldFilter(10)).to.eql(10);
|
||||
expect(goldFilter(10.0)).to.eql(10);
|
||||
expect(goldFilter(10.1)).to.eql(10);
|
||||
expect(goldFilter(10.2)).to.eql(10);
|
||||
expect(goldFilter(10.3)).to.eql(10);
|
||||
expect(goldFilter(10.4)).to.eql(10);
|
||||
expect(goldFilter(10.5)).to.eql(10);
|
||||
expect(goldFilter(10.6)).to.eql(10);
|
||||
expect(goldFilter(10.7)).to.eql(10);
|
||||
expect(goldFilter(10.8)).to.eql(10);
|
||||
expect(goldFilter(10.9)).to.eql(10);
|
||||
expect(goldFilter(11)).to.eql(11);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('silver', function() {
|
||||
it('converts decimal value of gold to silver', inject(function(silverFilter) {
|
||||
expect(silverFilter(10)).to.be.closeTo(0, 1);
|
||||
expect(silverFilter(10.01)).to.be.closeTo(1, 1);
|
||||
expect(silverFilter(10.05)).to.be.closeTo(5, 1);
|
||||
expect(silverFilter(10.17)).to.be.closeTo(17, 1);
|
||||
expect(silverFilter(10.23)).to.be.closeTo(23, 1);
|
||||
expect(silverFilter(10.25)).to.be.closeTo(25, 1);
|
||||
expect(silverFilter(10.53)).to.be.closeTo(53, 1);
|
||||
expect(silverFilter(10.75)).to.be.closeTo(75, 1);
|
||||
expect(silverFilter(10.99)).to.be.closeTo(99, 1);
|
||||
}));
|
||||
});
|
||||
});
|
||||
54
test/spec/filters/taskOrderingSpec.js
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
'use strict';
|
||||
|
||||
describe('Task Ordering Filters', function() {
|
||||
var filter
|
||||
, orderBySpy = sinon.spy();
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('orderByFilter', orderBySpy);
|
||||
});
|
||||
inject(function($rootScope, $filter) {
|
||||
filter = $filter;
|
||||
});
|
||||
});
|
||||
|
||||
describe('conditionalOrderBy', function() {
|
||||
describe('when the predicate is true', function() {
|
||||
it('delegates the arguments to the orderBy filter', function() {
|
||||
filter('conditionalOrderBy')('array', true, 'sortPredicate', 'reverseOrder');
|
||||
expect(orderBySpy).to.have.been.calledWith('array','sortPredicate','reverseOrder');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the predicate is false', function() {
|
||||
it('returns the initial array', function() {
|
||||
expect(filter('conditionalOrderBy')([1,2,3], false)).to.eql([1,2,3]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('filterByTextAndNotes', function () {
|
||||
it('returns undefined when no input given', function () {
|
||||
expect(filter('filterByTextAndNotes')()).to.eql(undefined);
|
||||
});
|
||||
|
||||
it('returns input if term is not a string', function () {
|
||||
var input = [1, 2, 3];
|
||||
expect(filter('filterByTextAndNotes')(input, '')).to.eql(input);
|
||||
expect(filter('filterByTextAndNotes')(input, undefined)).to.eql(input);
|
||||
expect(filter('filterByTextAndNotes')(input, [])).to.eql(input);
|
||||
expect(filter('filterByTextAndNotes')(input, new Date())).to.eql(input);
|
||||
});
|
||||
|
||||
it('filters items by notes and text', function () {
|
||||
var tasks = [
|
||||
{ text: 'foo' },
|
||||
{ text: 'foo', notes: 'bar' }
|
||||
];
|
||||
|
||||
expect(filter('filterByTextAndNotes')(tasks, 'bar')).to.eql([tasks[1]]);
|
||||
expect(filter('filterByTextAndNotes')(tasks, 'foo')).to.eql([tasks[0], tasks[1]]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
describe('Filters Controller', function() {
|
||||
var scope, user;
|
||||
|
||||
beforeEach(inject(function($rootScope, $controller, Shared) {
|
||||
user = specHelper.newUser();
|
||||
Shared.wrap(user);
|
||||
scope = $rootScope.$new();
|
||||
$controller('FiltersCtrl', {$scope: scope, User: {user: user}});
|
||||
}));
|
||||
|
||||
it('creates a tag', function(){
|
||||
scope._newTag = {name:'tagName'}
|
||||
scope.createTag();
|
||||
expect(user.tags).to.have.length(1);
|
||||
expect(user.tags[0].name).to.eql('tagName');
|
||||
expect(user.tags[0]).to.have.property('id');
|
||||
});
|
||||
|
||||
it('toggles tag filtering', inject(function(Shared){
|
||||
var tag = {id: Shared.uuid(), name: 'myTag'};
|
||||
scope.toggleFilter(tag);
|
||||
expect(user.filters[tag.id]).to.eql(true);
|
||||
scope.toggleFilter(tag);
|
||||
expect(user.filters[tag.id]).to.eql(false);
|
||||
}))
|
||||
});
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
describe('Custom Filters', function() {
|
||||
var filter
|
||||
, orderBySpy = sinon.spy();
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('orderByFilter', orderBySpy);
|
||||
});
|
||||
inject(function($rootScope, $filter) {
|
||||
filter = $filter;
|
||||
});
|
||||
});
|
||||
|
||||
describe('conditionalOrderBy', function() {
|
||||
describe('when the predicate is true', function() {
|
||||
it('delegates the arguments to the orderBy filter', function() {
|
||||
filter('conditionalOrderBy')('array', true, 'sortPredicate', 'reverseOrder');
|
||||
expect(orderBySpy).to.have.been.calledWith('array','sortPredicate','reverseOrder');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the predicate is false', function() {
|
||||
it('returns the initial array', function() {
|
||||
expect(filter('conditionalOrderBy')([1,2,3], false)).to.eql([1,2,3]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -35,3 +35,6 @@
|
|||
margin-right: 0.618em
|
||||
@extend $hrpg-button-with-input
|
||||
hrpg-button-color-mixin($color-options-submenu)
|
||||
.filters-search
|
||||
margin-bottom: 0.618em
|
||||
max-width: 180px
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ $color-toolbar = lighten($color-herobox, 70%)
|
|||
$color-options-menu = lighten($color-herobox, 85%)
|
||||
$color-options-submenu = lighten($color-herobox, 75%)
|
||||
// Button colors
|
||||
$color-button-style-one = $best
|
||||
$color-button-highlight = $best
|
||||
// Task background
|
||||
$color-tasks = lighten($color-herobox, 65%)
|
||||
// Task filter colors
|
||||
|
|
@ -37,4 +37,4 @@ $color-contributor-seven = #00aaff
|
|||
$color-contributor-mod = #130ead
|
||||
$color-contributor-staff = #88108f
|
||||
$color-contributor-npc = #000
|
||||
$color-contributor-npc-font = #00FF00
|
||||
$color-contributor-npc-font = #00FF00
|
||||
|
|
|
|||
|
|
@ -13,14 +13,21 @@ hrpg-text-shadow-mixin($hrpg-text-shadow-base-color)
|
|||
1px 1px 1px darken($hrpg-text-shadow-base-color,70%);
|
||||
// Buttons
|
||||
// The !important declarations override Bootstrap
|
||||
hrpg-button-color-mixin($hrpg-button-color)
|
||||
// buttons with the .highlight class pass highlight=true to this mixin
|
||||
hrpg-button-color-mixin($hrpg-button-color, highlight=false)
|
||||
// this case covers button elements with the highlight class
|
||||
// like the subscribe button, for which the following selectors do not apply
|
||||
if highlight==true
|
||||
border-color: darken($color-button-highlight, 16.18%) !important
|
||||
background-color: $color-button-highlight !important
|
||||
&
|
||||
color: darken($hrpg-button-color, 70%) !important
|
||||
hrpg-anchor-button-color-mixin($color-button-highlight)
|
||||
> a, > button
|
||||
background-color: $hrpg-button-color !important
|
||||
&:active
|
||||
background-color: darken($hrpg-button-color, 61.18%) !important
|
||||
@media screen and (min-width:768px)
|
||||
&:hover
|
||||
background-color: darken($hrpg-button-color, 2.36%) !important
|
||||
if highlight==true
|
||||
hrpg-anchor-button-color-mixin($color-button-highlight)
|
||||
else
|
||||
hrpg-anchor-button-color-mixin($hrpg-button-color)
|
||||
> a, > button, > input, textarea
|
||||
color: darken($hrpg-button-color, 70%) !important
|
||||
border-color: darken($hrpg-button-color, 16.18%) !important
|
||||
|
|
@ -38,6 +45,9 @@ hrpg-button-color-mixin($hrpg-button-color)
|
|||
&:active
|
||||
background-color: darken($hrpg-button-color, 16.18%) !important;
|
||||
> a:nth-of-type(2)
|
||||
if highlight==true
|
||||
border-left: 1px solid darken($color-button-highlight, 3.82%) !important
|
||||
else
|
||||
border-left: 1px solid darken($hrpg-button-color, 3.82%) !important
|
||||
> div
|
||||
@media screen and (min-width:768px)
|
||||
|
|
@ -69,6 +79,13 @@ hrpg-button-color-mixin($hrpg-button-color)
|
|||
color: #fff !important;
|
||||
span
|
||||
color: #fff !important;
|
||||
hrpg-anchor-button-color-mixin($hrpg-button-color)
|
||||
background-color: $hrpg-button-color !important
|
||||
&:active
|
||||
background-color: darken($hrpg-button-color, 61.18%) !important
|
||||
@media screen and (min-width:768px)
|
||||
&:hover
|
||||
background-color: darken($hrpg-button-color, 2.36%) !important
|
||||
$hrpg-button-master
|
||||
list-style: none
|
||||
> a, > button, > input, label::after
|
||||
|
|
@ -89,9 +106,8 @@ $hrpg-button
|
|||
> a, > button, > input, label::after
|
||||
border: 1px solid #ccc !important
|
||||
border-radius: 0.382em !important
|
||||
$hrpg-button-call-to-action
|
||||
@extend $hrpg-button
|
||||
hrpg-button-color-mixin($color-button-style-one)
|
||||
.highlight
|
||||
hrpg-button-color-mixin($color-toolbar, true)
|
||||
$hrpg-button-toggle
|
||||
@extend $hrpg-button-master
|
||||
border: 1px solid #ccc !important
|
||||
|
|
@ -100,6 +116,8 @@ $hrpg-button-toggle
|
|||
border-radius: 0.382em 0em 0em 0.382em !important
|
||||
> a:last-of-type
|
||||
border-radius: 0em 0.382em 0.382em 0em !important
|
||||
&.highlight
|
||||
hrpg-button-color-mixin($color-toolbar, true)
|
||||
// Input + Button
|
||||
$hrpg-button-with-input
|
||||
@extend $hrpg-button-master
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@
|
|||
@extend $hrpg-button-toggle
|
||||
@extend $hrpg-modal-dropdown-right
|
||||
hrpg-button-color-mixin($color-toolbar)
|
||||
&.highlight
|
||||
> a span.glyphicon
|
||||
margin-right: 0.382em !important
|
||||
.toolbar-button
|
||||
@extend $hrpg-button
|
||||
hrpg-button-color-mixin($color-toolbar)
|
||||
|
|
@ -163,7 +166,7 @@
|
|||
@extend $hrpg-button
|
||||
hrpg-button-color-mixin(lighten($color-toolbar,32.8%))
|
||||
.toolbar-subscribe-button, .toolbar-controls .toolbar-subscribe-button
|
||||
@extend $hrpg-button-call-to-action
|
||||
@extend $hrpg-button
|
||||
@media screen and (max-width:768px)
|
||||
.toolbar-toggle
|
||||
display: none
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ for $stage in $stages
|
|||
.color-{$stage[0]}:not(.completed)
|
||||
background-color: $stage[1]
|
||||
border: 1px solid shade($stage[1],10%)
|
||||
.priority-multiplier, .task-attributes, .repeat-days
|
||||
.priority-multiplier, .task-attributes, .repeat-days, .repeat-frequency
|
||||
li
|
||||
hrpg-button-color-mixin($stage[1])
|
||||
button
|
||||
|
|
@ -63,7 +63,7 @@ for $stage in $stages
|
|||
color: darken($completed,30%)
|
||||
background-color: $completed
|
||||
border: 1px solid shade($completed,10%)
|
||||
.priority-multiplier, .task-attributes, .repeat-days
|
||||
.priority-multiplier, .task-attributes, .repeat-days, .repeat-frequency
|
||||
li
|
||||
hrpg-button-color-mixin($completed)
|
||||
button
|
||||
|
|
@ -215,7 +215,6 @@ for $stage in $stages
|
|||
border: 1px solid #aaa
|
||||
border-radius: 0.382em
|
||||
padding-left: 0.618em
|
||||
background-color: #fff !important
|
||||
-webkit-appearance: none
|
||||
-moz-appearance: none
|
||||
appearance: none
|
||||
|
|
@ -410,6 +409,10 @@ form
|
|||
padding: 0 0 1em
|
||||
margin-bottom: 1em
|
||||
|
||||
button.advanced-options-toggle
|
||||
display: block;
|
||||
width: 100%;
|
||||
background: none;
|
||||
.option-title
|
||||
font-size: 1em
|
||||
margin: 0.5em 0 0.5em
|
||||
|
|
@ -507,7 +510,7 @@ form
|
|||
|
||||
form
|
||||
padding-bottom: 1em
|
||||
.priority-multiplier, .task-attributes, .repeat-days
|
||||
.priority-multiplier, .task-attributes, .repeat-days, .repeat-frequency
|
||||
text-align: center
|
||||
li
|
||||
@extend $hrpg-button
|
||||
|
|
@ -517,6 +520,7 @@ form
|
|||
&:last-of-type
|
||||
margin-right: 0
|
||||
.repeat-days
|
||||
padding-bottom: 1em
|
||||
li
|
||||
button
|
||||
min-width: 2.5em
|
||||
|
|
@ -524,6 +528,11 @@ form
|
|||
text-align: center
|
||||
@extend $hrpg-button
|
||||
|
||||
// Dailies
|
||||
.dailies
|
||||
.repeat-weekly
|
||||
padding-bottom: 1em
|
||||
|
||||
// Habits – task button styles (+ -)
|
||||
.habits
|
||||
.task-actions
|
||||
|
|
@ -580,7 +589,7 @@ form
|
|||
margin-top: 0.5em
|
||||
span
|
||||
margin-right: 0.5em
|
||||
> form
|
||||
> .checklist-form
|
||||
li
|
||||
@extend $hrpg-button-with-input
|
||||
@extend $clearfix
|
||||
|
|
|
|||
BIN
website/public/emails/images/PROMO-Enchanted-Armoire-v1.png
Normal file
|
After Width: | Height: | Size: 9 KiB |
|
|
@ -1,810 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://fonts.googleapis.com/css?family=Lato:400,700" rel='stylesheet' type="text/css">
|
||||
<title>HabitRPG | Gamify Your Life</title>
|
||||
|
||||
<meta name="description" content="">
|
||||
<meta name="keywords" content="">
|
||||
<meta name="author" content="">
|
||||
<meta name="geo.placename" content="">
|
||||
<!--[if IE]><meta http-equiv="imagetoolbar" content="no" /><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, maximum-scale=1" />
|
||||
|
||||
<meta property="og:title" content="" />
|
||||
<meta property="og:description" content="" />
|
||||
<meta property="og:url" content="" />
|
||||
<meta property="og:image" content="" />
|
||||
<meta property="og:site_name" content="" />
|
||||
|
||||
<link rel="canonical" href="" type="text/html" />
|
||||
<link rel="sitemap" type="application/xml" title="Sitemap" href="/sitemap.xml" />
|
||||
<link rel="shortcut icon" href="/images/favicon.png" />
|
||||
<link rel="apple-touch-icon" href="/images/apple-touch-icon.png" />
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||
|
||||
<!--Custom CSS-->
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
|
||||
<!-- Latest compiled and minified JavaScript -->
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header id="header">
|
||||
<nav class="navbar navbar-default navbar-static-top">
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#"><img src="images/icon175x175.png" />
|
||||
<img src="images/habitrpg_pixel.png" /></a>
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav nav-pills navbar-right">
|
||||
<li><a href="/howitworks">How it works</a></li>
|
||||
<li><a href="/enterprise">Corporate plans</a></li>
|
||||
<li><a href="/about">About us</a></li>
|
||||
<li><a href="http://blog.habitrpg.com/">Blog</a></li>
|
||||
<li><a href="">Press Kit</a></li>
|
||||
<li><a href="/contact">Contact us</a></li>
|
||||
<li><button id="header-play-button" class="btn btn-primary navbar-btn navbar-right">Play HabitRPG</button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div id="intro">
|
||||
<h1>Motivate yourself and your team!</h1>
|
||||
<img class="text-center" src="images/intro.jpg" /><!--insert intro images-->
|
||||
<div class="introcall bg-success">
|
||||
<h4>Join 200,000 players making it fun to achieve goals!
|
||||
<small><button class="btn btn-primary gamifybutton">Play for free</button></small>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="presslogos text-center">Featured in<br/>
|
||||
<img src="images/presslogos/lifehacker.png" />
|
||||
<img src="images/presslogos/nyt-logo.png" />
|
||||
<img src="images/presslogos/makeuseof.png" />
|
||||
<img src="images/presslogos/Forbes_logo.png" />
|
||||
<img src="images/presslogos/Cnetlogo.png" />
|
||||
<img src="images/presslogos/Fast-Company-logo.png" />
|
||||
<img src="images/presslogos/kickstarter-logo.png" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="intro-text" class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<p class="lead text-center">HabitRPG is a free habit building and productivity app that treats your real life like a game. With in-game rewards and punishments to motivate you and a strong social network to inspire you, HabitRPG can help you achieve your goals to become healthy, hard-working, and happy. </p>
|
||||
</div></div></div>
|
||||
|
||||
<section id="testimonial-carousel" class="bg-info">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-md-offset-1">
|
||||
<h2>What people say...</h2><br/>
|
||||
<img class="img-say img-responsive" src="images/uses/publicSpaces.png"/>
|
||||
</div>
|
||||
<!--Testimonials-->
|
||||
<div class="col-md-8">
|
||||
<div class="carousel slide" data-interval="4000" data-ride="carousel" id="quote-carousel">
|
||||
<!-- Bottom Carousel Indicators -->
|
||||
<ol class="carousel-indicators">
|
||||
<li data-target="#quote-carousel" data-slide-to="0" class="active"><img class="img-responsive " src="images/testimonials/Drag0nsilver.png" alt=""></li>
|
||||
<li data-target="#quote-carousel" data-slide-to="1"><img class="img-responsive " src="images/testimonials/frabjabulous.png" alt=""></li>
|
||||
<li data-target="#quote-carousel" data-slide-to="2"><img class="img-responsive " src="images/testimonials/AndeeLiao.png" alt=""></li>
|
||||
<li data-target="#quote-carousel" data-slide-to="3"><img class="img-responsive " src="images/testimonials/AlexandraSo.png" alt=""></li>
|
||||
</ol>
|
||||
<!-- Carousel Slides / Quotes -->
|
||||
<div class="carousel-inner text-center">
|
||||
<!-- Quote 1 -->
|
||||
<div class="item active">
|
||||
<blockquote>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-sm-offset-2"><p>I can't tell you how many time and task tracking systems I've tried over the decades... HRPG is the only thing I've used that actually helps me get things done rather than just list them.</p>
|
||||
<small>Drag0nsilver</small>
|
||||
</div>
|
||||
</div>
|
||||
</blockquote>
|
||||
</div>
|
||||
<!-- Quote 2 -->
|
||||
<div class="item">
|
||||
<blockquote>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-sm-offset-2">
|
||||
<p>HabitRPG is the reason I got a killer, high-paying job... and even more miraculous, I'm now a daily flosser!</p>
|
||||
<small>frabjabulous</small>
|
||||
</div>
|
||||
</div>
|
||||
</blockquote>
|
||||
</div>
|
||||
<!-- Quote 3 -->
|
||||
<div class="item">
|
||||
<blockquote>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-sm-offset-2">
|
||||
<p>Awesome product, just started a few days ago and already more conscious and productive with my time!</p>
|
||||
<small>AndeeLiao</small>
|
||||
</div>
|
||||
</div>
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="item">
|
||||
<blockquote>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-sm-offset-2">
|
||||
<p>Couldn't NOT talk about HabitRPG during my speech in Madrid. Must-have tool for freelancers who still need a boss.</p>
|
||||
<small>_AlexandraSo_</small>
|
||||
</div>
|
||||
</div>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Carousel Buttons Next/Prev -->
|
||||
<a data-slide="prev" href="#quote-carousel" class="left carousel-control"><i class="fa fa-chevron-left"></i></a>
|
||||
<a data-slide="next" href="#quote-carousel" class="right carousel-control"><i class="fa fa-chevron-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="uses">
|
||||
<h2>Players use HabitRPG to manage...</h2>
|
||||
<div class="container">
|
||||
<div id="myCarousel" class="carousel slide" data-ride="carousel">
|
||||
<ul class="nav nav-pills nav-justified">
|
||||
<li data-target="#myCarousel" data-slide-to="0" class="active"><a href="#">Work</a></li>
|
||||
<li data-target="#myCarousel" data-slide-to="1"><a href="#">Health</a></li>
|
||||
<li data-target="#myCarousel" data-slide-to="2"><a href="#">Teams</a></li>
|
||||
<li data-target="#myCarousel" data-slide-to="3"><a href="#">School</a></li>
|
||||
<li data-target="#myCarousel" data-slide-to="4"><a href="#">Goals</a></li>
|
||||
<li data-target="#myCarousel" data-slide-to="5"><a href="#">Chores</a></li>
|
||||
</ul>
|
||||
<!-- Wrapper for slides -->
|
||||
<div class="carousel-inner" style="z-index:0;">
|
||||
<div class="item active work-use">
|
||||
<h3>Work<br/><small><a href="/business.html">Use HabitRPG at your business</a></small></h3>
|
||||
<div class="carousel-content">
|
||||
<div class="sampletasks">
|
||||
<h4>Sample Habits</h4>
|
||||
<div style="width:19em; background-color: rgb(252, 229, 205); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(219, 120, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Confirm 1 page of Inventory</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(201, 218, 248); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(90, 98, 223); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">20 mins Filing</div></div><br />
|
||||
<div style="width:19em; background-color: #d9ead3; color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(113, 176, 91); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Sort and Process Inbox</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Prepare 1 Document for Client</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(244, 204, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(220, 93, 93); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div><div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; background-color: rgb(220, 93, 93); border-right: 0px none;">-</div><div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Call Clients/Put Off Phone Calls</div></div>
|
||||
</div>
|
||||
<img class="sample-img" src="images/uses/coding.png" />
|
||||
<div class="usetweet-groups">
|
||||
<div class="usetweet-group">
|
||||
<img data-toggle="tooltip" data-placement="top" title="frabjabulous" src="images/testimonials/frabjabulous.png">
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content">HabitRPG is the reason I got a killer, high-paying job... and even more miraculous, I'm now a daily flosser</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="usetweet-group">
|
||||
<img data-toggle="tooltip" data-placement="top" title="_AlexandraSo_" src="images/testimonials/AlexandraSo.png">
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content">Couldn't NOT talk about HabitRPG during my speech in Madrid. Must-have tool for freelancers who still need a boss.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--End item-->
|
||||
|
||||
<div class="item health-use">
|
||||
<h3>Health</h3>
|
||||
<div class="carousel-content">
|
||||
<div class="sampletasks">
|
||||
<h4>Sample Habits</h4>
|
||||
<div style="width:19em; background-color: #d9ead3; color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(113, 176, 91); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div><div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; background-color: rgb(113, 176, 91); border-right: 0px none;">-</div><div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Drink Water/Soda</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(244, 204, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(220, 93, 93); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div><div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; background-color: rgb(220, 93, 93); border-right: 0px none;">-</div><div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Chew Gum/Smoke</div></div><br />
|
||||
<div style="width:19em; background-color: #d9ead3; color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(113, 176, 91); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div><div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; background-color: rgb(113, 176, 91); border-right: 0px none;">-</div><div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Take Stairs/Elevator</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div><div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; background-color: rgb(255, 207, 66); border-right: 0px none;">-</div><div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Eat Healthy/Junk Food</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Break a Sweat for 1 hr</div></div>
|
||||
</div>
|
||||
|
||||
<img class="sample-img" src="images/uses/clipart-rosemonkeyct-meditation.png" />
|
||||
<div class="usetweet-group">
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/mwkelley/status/484390723585064960">The only reason I'm remembering to floss this week is because a sea serpent is attacking the tavern in @HabitRPG and that's weird but cool.</a></div>
|
||||
</div>
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/Myg/status/514095570936688641">Don't laugh, but I'm playing http://Habitrpg.com and it's making me walk around the house saying things like, "What vegetable can I eat?"</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Item -->
|
||||
<div class="item team-use">
|
||||
<h3>Teams</h3>
|
||||
<div class="carousel-content">
|
||||
<div class="sampletasks">
|
||||
<h4>Sample To-Dos</h4>
|
||||
<div style="width:19em; background-color: rgb(252, 229, 205); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(219, 120, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);"><span style="padding: 0.5em 0px 0em 0em; font-size: .8em; color: #666;">☐</span></div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Outline Meeting Itinerary for Tuesday</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);"><span style="padding: 0.5em 0px 0em 0em; font-size: .8em; color: #666;">☐</span></div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Brainstorm Growth Hacking</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(244, 204, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(220, 93, 93); border-right: 1px solid rgba(0, 0, 0, 0.25);"><span style="padding: 0.5em 0px 0em 0em; font-size: .8em; color: #666;">☐</span></div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Discuss this week’s KPIs</div></div><br />
|
||||
|
||||
</div>
|
||||
<img class="sample-img" src="images/uses/publicSpaces.png" />
|
||||
|
||||
<div class="usetweet-group">
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/tessa_racked/status/488024741278543872">HabitRPG! Because I won't do yoga and practice Spanish for their own benefits, but I will to get a giant mantis shrimp mount for my avatar.</a></div>
|
||||
</div>
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/kristenrapp/status/522771210602807296">Without @habitrpg I don't think I would have finished my novel draft.</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Item -->
|
||||
<div class="item school-use">
|
||||
<h3>School</h3>
|
||||
<div class="carousel-content">
|
||||
<div class="sampletasks">
|
||||
<h4>Sample Habits</h4>
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Finish 1 Assignment</div></div><br />
|
||||
<div style="width:19em; background-color: #d9ead3; color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(113, 176, 91); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Study 1 hour </div></div><br />
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Meet with Study Group</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(244, 204, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(220, 93, 93); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div><div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; background-color: rgb(220, 93, 93); border-right: 0px none;">-</div><div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Notes for 1 Chapter</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(201, 218, 248); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(90, 98, 223); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div><div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; background-color: rgb(90, 98, 223); border-right: 0px none;">-</div><div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Read 1 Chapter</div></div>
|
||||
</div>
|
||||
<img class="sample-img" src="images/uses/reading.png" />
|
||||
|
||||
<div class="usetweet-group">
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/alteriego/status/481560395048427520">My nerdiest venture yet: Using @habitrpg to gamify my to-do list. Because my thesis isn't gonna write itself</a></div>
|
||||
</div>
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/NightBlogger2/status/512040760250605568">Full-time graduate student and part-time TA. I need #habitrpg to keep my days organized and efficient on my quest to earn a Masters!</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Item -->
|
||||
<div class="item improvement-use">
|
||||
<h3>Goals</h3>
|
||||
<div class="carousel-content">
|
||||
<div class="sampletasks">
|
||||
<h4>Sample Habits</h4>
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Learn Something New </div></div><br />
|
||||
<div style="width:19em; background-color: #d9ead3; color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(113, 176, 91); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div><div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; background-color: rgb(113, 176, 91); border-right: 0px none;">-</div><div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Accept a Compliment</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Creative Session</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Do a Good Deed</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(201, 218, 248); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(90, 98, 223); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Read an Informative Article</div></div>
|
||||
</div>
|
||||
<img class="sample-img" src="images/uses/Gaining_an_achievement_by_cosmic_caterpillar-d7uyv5z.png" />
|
||||
|
||||
<div class="usetweet-group">
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/tessa_racked/status/488024741278543872">HabitRPG! Because I won't do yoga and practice Spanish for their own benefits, but I will to get a giant mantis shrimp mount for my avatar.</a></div>
|
||||
</div>
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/kristenrapp/status/522771210602807296">Without @habitrpg I don't think I would have finished my novel draft.</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Item -->
|
||||
|
||||
<div class="item housework-use">
|
||||
<h3>Chores</h3>
|
||||
<div class="carousel-content">
|
||||
<div class="sampletasks">
|
||||
<h4>Sample Habits</h4>
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Put Dirty Clothes in Hamper</div></div><br />
|
||||
<div style="width:19em; background-color: #d9ead3; color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(113, 176, 91); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div><div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; background-color: rgb(113, 176, 91); border-right: 0px none;">-</div><div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">20 mins of Housework</div></div><br />
|
||||
<div style="width:19em; background-color: #d9ead3; color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(113, 176, 91); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div><div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; background-color: rgb(113, 176, 91); border-right: 0px none;">-</div><div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Wash a Load of Dishes</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(255, 242, 204); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(255, 207, 66); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Tidy One Room</div></div><br />
|
||||
<div style="width:19em; background-color: rgb(201, 218, 248); color: rgb(51, 51, 51); text-align:center; padding: 0px; font-size: 1.41em; line-height: 1.62765; list-style: none outside none; padding: 0px; height: 2.3em; min-height: 1.62765em; margin-bottom:0.75em; margin:0px; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5) inset;">
|
||||
<div style="display: inline-block; width: 1.62765em; height: 1.62765em; padding: 0px; margin:0px; font-size: 1.41em; line-height: 1.62765; text-align: center; color: rgb(34, 34, 34); float:left; cursor: pointer; vertical-align: top; left:0px; position:relative; background-color: rgb(90, 98, 223); border-right: 1px solid rgba(0, 0, 0, 0.25);">+</div> <div style="display: inline-block; font-family: Lato,sans-serif; padding: 0.6em 0px 0em 1em; font-size: .8em; letter-spacing: normal; float:left; word-wrap: break-word;">Wash and Dry a Load of Clothes</div></div>
|
||||
</div>
|
||||
<img class="sample-img" src="images/uses/dusting_by_leephon.png" />
|
||||
<div class="usetweet-group">
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/wholemilk/status/483341884929359872">Just did all the dishes AND scrubbed the sink, all for imaginary internet points! Thanks @habitrpg!</a></div>
|
||||
</div>
|
||||
<div class="usetweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/Caroline_Eising/status/553484464794267648">Remembered @habitrpg and started using it again. Today I cleaned the light fittings, which I have meant to do for at least a year #itworks</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Item -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Carousel -->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="quest-intro">
|
||||
<h2 data-anchor-target="#rewards" data-500-bottom-top="opacity:0;position:fixed;right:0;top:0%;" data-50-bottom-top="opacity:1; top:35%;" data-center-center="top:-50%;">Join us on a mini-quest!<br/><span class="glyphicon glyphicon-chevron-down"></span></h2>
|
||||
<!--Avatar fades in from behind, is affixed to travel at the center of the page all the way down until it hits the footer call-to-action-->
|
||||
<img id="myAvatar" data--200-bottom-bottom="opacity:0;" data-center-center="display:block;position:fixed;right:10%;top:40%;opacity:1;" data-260-end="top:40%;" data-end="top:3%" data-edge-strategy="set" src="images/avatar/avatar.png" />
|
||||
</section>
|
||||
|
||||
<section id="rewards" class="bg-warning">
|
||||
<h2 class="headline">Complete a task to earn gold!</h2>
|
||||
<div class="avatarscroll">
|
||||
<h2 data-center-bottom="opacity:0;" data-120-top-center="opacity:1;"><span class="glyphicon glyphicon-check"></span></h2>
|
||||
<img data-center-bottom="opacity:0;" data-180-top-center="opacity:1;" src="images/misc/shop_gold.png" /><img data-center-bottom="opacity:0;" data-180-top-center="opacity:1;" src="images/misc/shop_gold.png" /><img data-center-bottom="opacity:0;" data-180-top-center="opacity:1;" src="images/misc/shop_gold.png" /><br/>
|
||||
<img data-center-bottom="opacity:0;" data-220-top-center="opacity:1;" src="images/TVreward.png" />
|
||||
|
||||
</div>
|
||||
|
||||
<!--3rd level equipment fades in on avatar, gets affixed until more equipment presented in Features area-->
|
||||
|
||||
<p class="sectioninfo">Spend gold on virtual and real-life rewards.<br/><br/>Instant rewards keep you motivated!</p>
|
||||
|
||||
<div class="scrolltweet scrolltweet-right">
|
||||
<img class="speech-bubble" src="images/testimonial_by_Streak.png" />
|
||||
<img class="scrolltweet-image" data-toggle="popover" data-placement="top" data-container="body" data-content="I really like HabitRPG. I did a bunch of jumping jacks because I needed a bit more gold for a helmet. -tonitonirocca" src="images/testimonials/Drag0nsilver.png" />
|
||||
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5 col-md-offset-1">
|
||||
<div class="scrolltweet tweet popover left">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href-"https://twitter.com/L0stPuppy/status/507034694970781696">I just found myself drinking more water so I could buy some leather armor. #habitrpg<span class="tweep">@L0stPuppy</span></a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="levels">
|
||||
<h2 class="headline">As you stay productive, you unlock new content!</h2>
|
||||
<div class="avatarscroll quest-classes">
|
||||
<img data-bottom-bottom="display:block;opacity:0;margin-top:15%;right:200%;" data-center-center="display:block;opacity:1;right:80%;" src="images/Healer.png" />
|
||||
<img data-bottom-bottom="display:block;opacity:0;left:200%;" data-center-center="display:block;opacity:1;margin-top:15%;left:80%;" src="images/Rogue.png" />
|
||||
<img data-bottom-bottom="display:block;opacity:0;margin-top:40%;left:200%;" data-center-center="display:block;opacity:1;margin-top:36%;left:80%;" src="images/Wizard.png" />
|
||||
<img data-bottom-bottom="display:block;opacity:0;margin-top:45%;right:200%;" data-center-center="display:block;opacity:1;margin-top:40%;right:80%;" src="images/Warrior.png" />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div data-center-center="opacity:0;" data-150-top-center="display:block;position:fixed;right:10%;top:37%;opacity:1;" data-640-end="top:37%;opacity:1;" data-620-end="opacity:0;" data-edge-strategy="set" class="scroll-armor">
|
||||
<img class="armor" src="images/avatar/head_warrior_3.png" />
|
||||
<img class="armor" src="images/avatar/shield_warrior_3.png" />
|
||||
<img class="armor" src="images/avatar/slim_armor_warrior_3.png" />
|
||||
<img class="armor" src="images/avatar/weapon_warrior_3.png" />
|
||||
</div>
|
||||
<div data-center-center="opacity:0;" data-150-top-center="display:block;position:fixed;right:10%;top:53%;z-index:3;opacity:1;" data-260-end="top:53%;" data-end="top:16%" data-edge-strategy="set" class="quest-pet">
|
||||
<img src="images/Pet-Fox-Red.png" />
|
||||
</div>
|
||||
|
||||
<!--Dragon pet and class costumes come in from sides-->
|
||||
|
||||
<p class="sectioninfo">Achieve your goals and level up.<br/><br/>Unlock new motivational tools, such as pet collecting, random rewards, spell-casting, and more!</p>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-5 col-md-offset-7">
|
||||
<div class="scrolltweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/NatJeanMiller/status/505598740242001920">I'm level 30 and riding a dragon #winning</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5 col-md-offset-1">
|
||||
<div class="scrolltweet tweet popover left">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href-"https://twitter.com/ClaireThalken/status/466631598847574017">Woot! I reached level ten on HabitRPG and switched my class from warrior to rogue. Now I get to hold TWO weapons.</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="health" class="bg-danger">
|
||||
<h2 class="headline">Miss a daily goal?</h2>
|
||||
|
||||
<!--Progress bar appears next to avatar, decreases on scroll. Probably will require SVG animation-->
|
||||
|
||||
<div class="health-progress">
|
||||
<div tooltip="Health" class="meter-label">
|
||||
<span class="glyphicon glyphicon-heart"></span>
|
||||
</div>
|
||||
<div class="meter health">
|
||||
<div class="bar"><div data-center-center="width:100%;" data-200-top-top="width:50%;"> </div></div>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Lose health!</h2>
|
||||
<p class="sectioninfo">Break bad habits and procrastination cycles with immediate consequences.</p>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-5 col-md-offset-7">
|
||||
<div class="scrolltweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/kevinpurdy/status/494498960116293633">Pleasantly surprised how well I'm sticking to @habitrpg as a task list/habit enforcer. A lifetime of watching health meters pays off.<span class="tweep">@kevinpurdy</span></a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5 col-md-offset-1">
|
||||
<div class="scrolltweet tweet popover left">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/soft_lit/status/560231146467127297">I need to stop neglecting habitrpg otherwise my little dude will die soon<span class="tweep">@soft_lit</span></a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="quest">
|
||||
<h2 class="headline">Battle monsters with your friends!</h2>
|
||||
|
||||
<!--Boss image background, with other avatars present. Their progress bars decrease on scroll. The one on the bottom right corner could die, haha-->
|
||||
<div class="quest-friend quest-left">
|
||||
<div class="quest-friend-health">
|
||||
<div tooltip="Health" class="meter-label">
|
||||
<span class="glyphicon glyphicon-heart"></span></div>
|
||||
<div class="meter health">
|
||||
<div class="bar"><div data-center-center="width:90%;" data-200-top-top="width:30%;"> </div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quest-friend-img"><img src="images/party/AnnaCosplay.png" /></div>
|
||||
|
||||
</div>
|
||||
<div class="quest-friend quest-right">
|
||||
<div class="quest-friend-health">
|
||||
<div tooltip="Health" class="meter-label">
|
||||
<span class="glyphicon glyphicon-heart"></span></div>
|
||||
<div class="meter health">
|
||||
<div class="bar"><div data-center-center="width:40%;" data-200-top-top="width:0%;"> </div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quest-friend-img" data-bottom-bottom='background: url("images/party/HomeStuckLusus.png") no-repeat left top;' data-220-top-top='background: url("images/party/GrimReaper.png")no-repeat center top;'></div>
|
||||
</div>
|
||||
|
||||
<h2>If you slack off, they all get hurt!</h2>
|
||||
<p class="sectioninfo">Playing with your friends keeps you accountable for your tasks.<br/>Issue each other Challenges to complete a goal together!</p>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-5 col-md-offset-7">
|
||||
<div class="scrolltweet tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/DejiNyucu/status/429211504726900737">Oh, we did it! we completed our first quest in #HabitRPG as a party and we got the polar bear mount!<span class="tweep">@DejiNyucu</span></a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5 col-md-offset-1">
|
||||
<div class="scrolltweet tweet popover left">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/korybing/status/539135640072253440">oh shoot I forgot to check off a couple dailies on my habitrpg I'M SORRY, HABITRPG PARTY.<span class="tweep">@korybing</span></a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<div id="features" class="bg-info">
|
||||
<h2>We also feature...</h2>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<!--Pets and mount fade-in. Need to think about how to sticky it to the avatar-->
|
||||
<div class="col-md-1 col-md-offset-6 quest-mount">
|
||||
<img data-100-center-center="opacity:0;" data-40-center-center="display:block;position:fixed;top:46%;opacity:1;" data-260-end="top:46%;" data-end="top:9%" data-edge-strategy="set" class="mount" src="images/Mount_Body_Wolf-Base.png" />
|
||||
<img data-100-center-center="opacity:0;" data-40-center-center="display:block;position:fixed;top:46%;opacity:1;" data-260-end="top:46%;" data-end="top:9%" data-edge-strategy="set" class="mount mount-head" src="images/Mount_Head_Wolf-Base.png" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="featuretext">
|
||||
<h4>Pets and Mounts</h4>
|
||||
<p>Eggs and items drop when you complete your tasks. Be as productive as possible to collect pets and mounts!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-md-offset-1">
|
||||
<div class="scrolltweet tweet popover bottom">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-title"><strong>You're Resting in the Inn</strong></div>
|
||||
<div class="popover-content"><p>The Zzz's over your avatar's head means you are <a href="http://habitrpg.wikia.com/wiki/Tavern#Resting_in_the_Inn">Resting in the Inn</a>.</p><p>Your Dailies won't reset until you check out.</p>
|
||||
<button class="btn btn-sm btn-block btn-default">I'm still resting but remind me tomorrow</button>
|
||||
<button class="btn btn-block btn-default">Don't remind me again</button>
|
||||
<button class="btn btn-block btn-primary">Check out of inn</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
|
||||
<div class="row">
|
||||
<!--Achievemnt badge fade-in-->
|
||||
<div class="col-md-1 col-md-offset-6">
|
||||
<img data-50-center-center="opacity:0;" data--40-center-center="display:block;position:fixed;top:44%;left:55%;opacity:1;" data-260-end="top:44%;" data-end="top:6%" data-edge-strategy="set" src="images/achievement-triadbingo.png" />
|
||||
<img data-50-center-center="opacity:0;" data--40-center-center="display:block;position:fixed;top:49%;left:55%;opacity:1;" data-260-end="top:49%;" data-end="top:11%" data-edge-strategy="set" src="images/achievement-perfect.png" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="featuretext">
|
||||
<h4>Achievement Badges</h4>
|
||||
<p>Do something totally awesome? Get a badge and show it off!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<!--Level 5 equipment fade-in, with candy/potion/quest scroll. Level 5 equipment stickies on avatar all the way down-->
|
||||
<div class="col-md-1 col-md-offset-6 quest-warrior">
|
||||
<img data-100-center-center="opacity:0;" data-40-center-center="display:block;position:fixed;top:39%;opacity:1;" data-260-end="top:39%;" data-end="top:2%" data-edge-strategy="set" class="warrior-5" src="images/avatar/head_warrior_5.png" />
|
||||
<img data-100-center-center="opacity:0;" data-40-center-center="display:block;position:fixed;top:39%;opacity:1;" data-260-end="top:39%;" data-end="top:2%" data-edge-strategy="set" class="warrior-5" src="images/avatar/shield_warrior_5.png" />
|
||||
<img data-100-center-center="opacity:0;" data-40-center-center="display:block;position:fixed;top:39%;opacity:1;" data-260-end="top:39%;" data-end="top:2%" data-edge-strategy="set" class="warrior-5" src="images/avatar/slim_armor_warrior_5.png" />
|
||||
<img data-100-center-center="opacity:0;" data-40-center-center="display:block;position:fixed;top:39%;opacity:1;" data-260-end="top:39%;" data-end="top:2%" data-edge-strategy="set" class="warrior-5" src="images/avatar/weapon_warrior_5.png" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="featuretext">
|
||||
<h4>Equipment and extras</h4>
|
||||
<p>Buy limited edition equipment, potions, and other virtual goodies in our Market with your task rewards!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<!--other avatars fly gin from sides to be next to main avatar-->
|
||||
<div class="col-md-1 col-md-offset-6">
|
||||
<img data-100-center-center="left:-100%;" data-50-center-center="position:fixed;top:45%;left:0%;" data-end="top:6%" data-edge-strategy="set" src="images/Party-Header.png" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="featuretext">
|
||||
<h4>Social play</h4>
|
||||
<p>Join common-interest groups with like-minded people.<br/><br/>Create Challenges to compete against other users.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <section id="testimonials">
|
||||
<h2>What people say...</h2>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-5 col-md-offset-7">
|
||||
<div class="testimonialgroup">
|
||||
<div class="testimonial tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/MayLHarrison/status/559440289556103169">Can't remember how I kept control of my life before @habitrpg. Best tool I've ever found for becoming the best version of myself I can be.</a></div>
|
||||
</div>
|
||||
<img class="tweeppic" />
|
||||
<span class="tweep">@MayLHarrison</span>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5 col-md-offset-1">
|
||||
<div class="testimonialgroup">
|
||||
<div class="testimonial tweet popover left">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/wholemilk/status/484533856864071680">Thank you, @habitrpg , I have now run five mornings in a row, my house is cleaner, and I'm drinking more water!</a></div>
|
||||
</div>
|
||||
<img class="tweeppic" />
|
||||
<span class="tweep">@wholemilk</span>
|
||||
</div></div></div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5 col-md-offset-7">
|
||||
|
||||
<div class="testimonialgroup">
|
||||
<div class="testimonial tweet popover right">
|
||||
<div class="arrow"></div>
|
||||
<div class="popover-content"><a href="https://twitter.com/mattjoehunt/status/559613163654905856">The best game I have ever played is @habitrpg - I have never been more productive.</a></div>
|
||||
</div>
|
||||
<img class="tweeppic" />
|
||||
<span class="tweep">@mattjoehunt</span>
|
||||
</div>
|
||||
</div></div></div>
|
||||
</section> -->
|
||||
|
||||
<div id="footercall">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-md-offset-7">
|
||||
<h3>Join 200,000 players making it fun to achieve goals!</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
<button class="btn btn-primary btn-lg btn-block">Play for free!</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<footer class="footer">
|
||||
<div class="container-fluid shoutout">
|
||||
<h4>HabitRPG <3s</h4>
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1"><a href="http://ionicframework.com/"><img src="images/presslogos/ionic-logo-horizontal-transparent.png"></a></div>
|
||||
<div class="col-md-2"><a href="https://www.jetbrains.com/webstorm/"><img src="images/presslogos/logo_webstorm.png"></a></div>
|
||||
<div class="col-md-2"><a href="http://github.com/"><img src="images/presslogos/GitHub_Logo.png"></a></div>
|
||||
<div class="col-md-2"><a href="https://trello.com/"><img src="images/presslogos/trello-logo-blue.png"></a></div>
|
||||
<div class="col-md-2"><a href="https://slack.com/"><img src="images/presslogos/landing_slack_hash_wordmark_logo.png"></a></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row footer-content">
|
||||
<div class="col-md-2 col-md-offset-2">
|
||||
<h4>Mobile</h4>
|
||||
<ul class="list-unstyled">
|
||||
<li><a href="https://itunes.apple.com/us/app/habitrpg/id689569235?mt=8" target="_blank">iOS</a></li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=com.ocdevel.habitrpg" target="_blank">Android</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<h4>Company</h4>
|
||||
<ul class="list-unstyled">
|
||||
<li><a href="/static/features">Features</a></li>
|
||||
<li><a target="_blank" href="http://blog.habitrpg.com/">Blog</a></li>
|
||||
<li><a target="_blank" href="http://habitrpg.wikia.com/wiki/FAQ">FAQ</a></li>
|
||||
<li><a href="/static/privacy">Privacy</a></li>
|
||||
<li><a href="/static/terms">Terms</a></li>
|
||||
<li><a href="/static/contact">Contact Us</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<h4>Community</h4>
|
||||
<ul class="list-unstyled">
|
||||
<li><a target="_blank" href="https://habitrpg.com/static/api">API</a></li>
|
||||
<li><a href="http://habitrpg.wikia.com/wiki/App_and_Extension_Integrations" target="_blank">Add-ons & Extensions</a></li>
|
||||
<li><a target="_blank" href="http://habitrpg.wikia.com/wiki/Special:Forum">Forum</a></li>
|
||||
<li><a target="_blank" href="http://www.kickstarter.com/projects/lefnire/habitrpg-mobile">Kickstarter</a></li>
|
||||
<li><a target="_blank" href="https://www.facebook.com/Habitrpg">Facebook</a></li>
|
||||
<li><a target="_blank" href="http://www.reddit.com/r/habitrpg/">Reddit</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<h4>Social</h4>
|
||||
<div addthis:url="https://habitrpg.com" addthis:title="HabitRPG - Gamify Your Life" class="addthis_toolbox addthis_default_style">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a fb:like:layout="button_count" class="addthis_button_facebook_like"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a tw:via="habitrpg" class="addthis_button_tweet"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<!-- <td><iframe src="http://www.habitrpg.com/bower_components/github-buttons/github-btn.html?user=lefnire&repo=habitrpg&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="85px" height="20px"></iframe></td> -->
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a g:plusone:size="medium" class="addthis_button_google_plusone"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!--Fixed CTA-->
|
||||
<button data-anchor-target=".gamifybutton" data-top="opacity:0;" data--100-top="opacity:1;" data-500-end="opacity:1;" data-400-end="opacity:0;" class="btn btn-info fixedcta">Gamify your life today!</button>
|
||||
|
||||
|
||||
<!-- Footer scripts -->
|
||||
<!--Use carousel initialize-->
|
||||
<script type="text/javascript">
|
||||
$(document).ready( function() {
|
||||
$('#myCarousel').carousel({
|
||||
interval: false
|
||||
});
|
||||
|
||||
var clickEvent = false;
|
||||
$('#myCarousel').on('click', '.nav a', function() {
|
||||
clickEvent = true;
|
||||
$('.nav li').removeClass('active');
|
||||
$(this).parent().addClass('active');
|
||||
}).on('slid.bs.carousel', function(e) {
|
||||
if(!clickEvent) {
|
||||
var count = $('.nav').children().length -1;
|
||||
var current = $('.nav li.active');
|
||||
current.removeClass('active').next().addClass('active');
|
||||
var id = parseInt(current.data('slide-to'));
|
||||
if(count == id) {
|
||||
$('.nav li').first().addClass('active');
|
||||
}
|
||||
}
|
||||
clickEvent = false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--Skroller init-->
|
||||
<script type="text/javascript" src="js/skrollr.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var s = skrollr.init();
|
||||
</script>
|
||||
|
||||
<!--Tooltips-->
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
$('[data-toggle="popover"]').popover()
|
||||
})
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1 +0,0 @@
|
|||
<!-- See /website/views/static/front -->
|
||||
|
|
@ -19,7 +19,9 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
|
|||
$scope.challenges = challenges;
|
||||
$scope.groupsFilter = _.uniq(_.pluck(challenges, 'group'), function(g){return g._id});
|
||||
$scope.search = {
|
||||
group: _.transform($scope.groups, function(m,g){m[g._id]=true;})
|
||||
group: _.transform($scope.groups, function(m,g){m[g._id]=true;}),
|
||||
_isMember: "either",
|
||||
_isOwner: "either"
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
@ -254,18 +256,10 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
|
|||
// Filtering
|
||||
//------------------------------------------------------------
|
||||
|
||||
// $scope.$watch('search', function(search){
|
||||
// if (!search) $scope.filteredChallenges = $scope.challenges;
|
||||
// $scope.filteredChallenges = $filter('filter')($scope.challenges, function(chal) {
|
||||
// return (search.group[chal.group._id] &&
|
||||
// (typeof search._isMember == 'undefined' || search._isMember == chal._isMember));
|
||||
// })
|
||||
// })
|
||||
// TODO probably better to use $watch above, to avoid this being calculated on every digest cycle
|
||||
$scope.filterChallenges = function(chal){
|
||||
return (!$scope.search) ? true :
|
||||
($scope.search.group[chal.group._id] &&
|
||||
(typeof $scope.search._isMember == 'undefined' || $scope.search._isMember == chal._isMember));
|
||||
if (!$scope.search) return true;
|
||||
|
||||
return _shouldShowChallenge(chal);
|
||||
}
|
||||
|
||||
$scope.$watch('newChallenge.group', function(gid){
|
||||
|
|
@ -286,4 +280,16 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
|
|||
$scope.shouldShow = function(task, list, prefs){
|
||||
return true;
|
||||
};
|
||||
|
||||
function _shouldShowChallenge(chal) {
|
||||
// Have to check that the leader object exists first in the
|
||||
// case where a challenge's leader deletes their account
|
||||
var userIsOwner = (chal.leader && chal.leader._id) == User.user.id;
|
||||
|
||||
var groupSelected = $scope.search.group[chal.group._id];
|
||||
var checkOwner = $scope.search._isOwner === 'either' || (userIsOwner === $scope.search._isOwner);
|
||||
var checkMember = $scope.search._isMember === 'either' || (chal._isMember === $scope.search._isMember);
|
||||
|
||||
return groupSelected && checkOwner && checkMember;
|
||||
}
|
||||
}]);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ habitrpg.controller("FiltersCtrl", ['$scope', '$rootScope', 'User', 'Shared',
|
|||
var user = User.user;
|
||||
$scope._editing = false;
|
||||
$scope._newTag = {name:''};
|
||||
$scope.filterQuery = '';
|
||||
|
||||
var tagsSnap; // used to compare which tags need updating
|
||||
|
||||
|
|
@ -30,6 +31,11 @@ habitrpg.controller("FiltersCtrl", ['$scope', '$rootScope', 'User', 'Shared',
|
|||
// User.save();
|
||||
};
|
||||
|
||||
$scope.updateTaskFilter = function(){
|
||||
user.filterQuery = $scope.filterQuery;
|
||||
};
|
||||
$scope.updateTaskFilter();
|
||||
|
||||
$scope.createTag = function() {
|
||||
User.user.ops.addTag({body:{name:$scope._newTag.name, id:Shared.uuid()}});
|
||||
$scope._newTag.name = '';
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
|
|||
function($scope, $rootScope, $location, User, Notification, $http, ApiUrl, $timeout, Shared, Guide) {
|
||||
$scope.obj = User.user; // used for task-lists
|
||||
$scope.user = User.user;
|
||||
|
||||
$scope.armoireCount = function(gear) {
|
||||
return Shared.countArmoire(gear);
|
||||
};
|
||||
|
|
@ -131,6 +132,19 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
|
|||
*/
|
||||
$scope._today = moment().add({days: 1});
|
||||
|
||||
/*
|
||||
------------------------
|
||||
Dailies
|
||||
------------------------
|
||||
*/
|
||||
|
||||
$scope.openDatePicker = function($event, task) {
|
||||
$event.preventDefault();
|
||||
$event.stopPropagation();
|
||||
|
||||
task._isDatePickerOpen = !task._isDatePickerOpen;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------
|
||||
Checklists
|
||||
|
|
@ -216,7 +230,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
|
|||
$scope.shouldShow = function(task, list, prefs){
|
||||
if (task._editing) // never hide a task while being edited
|
||||
return true;
|
||||
var shouldDo = task.type == 'daily' ? habitrpgShared.shouldDo(new Date, task.repeat, prefs) : true;
|
||||
var shouldDo = task.type == 'daily' ? habitrpgShared.shouldDo(new Date, task, prefs) : true;
|
||||
switch (list.view) {
|
||||
case "yellowred": // Habits
|
||||
return task.value < 1;
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
angular.module('habitrpg')
|
||||
.filter('gold', function () {
|
||||
return function (gp) {
|
||||
return Math.floor(gp);
|
||||
}
|
||||
})
|
||||
.filter('silver', function () {
|
||||
return function (gp) {
|
||||
return Math.floor((gp - Math.floor(gp))*100);
|
||||
}
|
||||
})
|
||||
.filter('htmlDecode',function(){
|
||||
return function(html){
|
||||
return $('<div/>').html(html).text();
|
||||
}
|
||||
})
|
||||
.filter('goldRoundThousandsToK', function(){
|
||||
return function (gp) {
|
||||
return (gp > 999999999) ? (gp / Math.pow(10, 9)).toFixed(1) + "b" :
|
||||
(gp > 999999) ? (gp / Math.pow(10, 6)).toFixed(1) + "m" :
|
||||
(gp > 999) ? (gp / Math.pow(10, 3)).toFixed(1) + "k" : gp;
|
||||
}
|
||||
})
|
||||
.filter('conditionalOrderBy', ['$filter', function($filter) {
|
||||
return function (array, predicate, sortPredicate, reverseOrder) {
|
||||
if (predicate) {
|
||||
return $filter('orderBy')(array, sortPredicate, reverseOrder);
|
||||
}
|
||||
return array;
|
||||
};
|
||||
}]);
|
||||
11
website/public/js/filters/money.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
angular.module('habitrpg')
|
||||
.filter('gold', function () {
|
||||
return function (gp) {
|
||||
return Math.floor(gp);
|
||||
}
|
||||
})
|
||||
.filter('silver', function () {
|
||||
return function (gp) {
|
||||
return Math.floor((gp - Math.floor(gp))*100);
|
||||
}
|
||||
});
|
||||
30
website/public/js/filters/roundLargeNumbers.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
angular.module('habitrpg')
|
||||
.filter('roundLargeNumbers', function(){
|
||||
return function (num) {
|
||||
return _calculateRoundedNumber(num);
|
||||
}
|
||||
});
|
||||
|
||||
function _calculateRoundedNumber(num) {
|
||||
if (num > 999999999) {
|
||||
return _convertToBillion(num);
|
||||
} else if (num > 999999) {
|
||||
return _convertToMillion(num);
|
||||
} else if (num > 999) {
|
||||
return _convertToThousand(num);
|
||||
} else {
|
||||
return num;
|
||||
}
|
||||
}
|
||||
|
||||
function _convertToThousand(num) {
|
||||
return (num / Math.pow(10, 3)).toFixed(1) + "k";
|
||||
}
|
||||
|
||||
function _convertToMillion(num) {
|
||||
return (num / Math.pow(10, 6)).toFixed(1) + "m";
|
||||
}
|
||||
|
||||
function _convertToBillion(num) {
|
||||
return (num / Math.pow(10, 9)).toFixed(1) + "b";
|
||||
}
|
||||
30
website/public/js/filters/taskOrdering.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
angular.module('habitrpg')
|
||||
.filter('conditionalOrderBy', ['$filter', function($filter) {
|
||||
return function (array, predicate, sortPredicate, reverseOrder) {
|
||||
if (predicate) {
|
||||
return $filter('orderBy')(array, sortPredicate, reverseOrder);
|
||||
}
|
||||
return array;
|
||||
};
|
||||
}])
|
||||
.filter('filterByTextAndNotes', ['$filter', function($filter) {
|
||||
return function (input, term) {
|
||||
if (!input) return;
|
||||
|
||||
if (!angular.isString(term) || term.legth === 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
term = new RegExp(term, 'i');
|
||||
|
||||
var result = [];
|
||||
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if (term.test(input[i].text) || term.test(input[i].notes)) {
|
||||
result.push(input[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}]);
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
"js/app.js",
|
||||
"common/script/public/config.js",
|
||||
|
||||
"js/services/sharedServices.js",
|
||||
"js/services/notificationServices.js",
|
||||
"common/script/public/userServices.js",
|
||||
|
|
@ -48,7 +49,9 @@
|
|||
"js/services/challengeServices.js",
|
||||
"js/services/paymentServices.js",
|
||||
|
||||
"js/filters/filters.js",
|
||||
"js/filters/money.js",
|
||||
"js/filters/roundLargeNumbers.js",
|
||||
"js/filters/taskOrdering.js",
|
||||
|
||||
"js/directives/focus-me.directive.js",
|
||||
"js/directives/from-now.directive.js",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ var mongoose = require("mongoose");
|
|||
var Schema = mongoose.Schema;
|
||||
var shared = require('../../../common');
|
||||
var _ = require('lodash');
|
||||
var moment = require('moment');
|
||||
|
||||
// Task Schema
|
||||
// -----------
|
||||
|
|
@ -50,10 +51,13 @@ var checklist = [{
|
|||
|
||||
var DailySchema = new Schema(
|
||||
_.defaults({
|
||||
type: {type:String, 'default': 'daily'},
|
||||
type: {type: String, 'default': 'daily'},
|
||||
frequency: {type: String, 'default': 'weekly', enum: ['daily', 'weekly']},
|
||||
everyX: {type: Number, 'default': 1}, // e.g. once every X weeks
|
||||
startDate: {type: Date, 'default': moment().startOf('day').toDate()},
|
||||
history: Array,
|
||||
completed: {type: Boolean, 'default': false},
|
||||
repeat: {
|
||||
repeat: { // used only for 'weekly' frequency,
|
||||
m: {type: Boolean, 'default': true},
|
||||
t: {type: Boolean, 'default': true},
|
||||
w: {type: Boolean, 'default': true},
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ html(ng-app="habitrpg", ng-controller="RootCtrl", ng-class='{"applying-action":a
|
|||
include ./shared/header/menu
|
||||
include ./shared/modals/index
|
||||
include ./shared/header/header
|
||||
include ./shared/tasks/lists
|
||||
include ./shared/tasks/index
|
||||
include ./main/index
|
||||
include ./options/index
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
.container-fluid
|
||||
.row
|
||||
.filters(ng-controller='FiltersCtrl')
|
||||
.input-group.input-group-sm.filters-search.pull-right
|
||||
input.form-control(type='text', placeholder=env.t('search'), ng-model='filterQuery', ng-change='updateTaskFilter()', ng-model-options='{ debounce: 250 }')
|
||||
.input-group-addon
|
||||
.glyphicon.glyphicon-search
|
||||
ul.filters-controls
|
||||
li=env.t('tags')
|
||||
//- Edit button
|
||||
|
|
|
|||
|
|
@ -52,13 +52,13 @@ mixin boss(tavern, mobile)
|
|||
.meter.health
|
||||
.bar(style='width: {{Shared.percent(progress.hp, boss.hp)}}%;')
|
||||
span.meter-text.value
|
||||
| {{Math.ceil(progress.hp) | goldRoundThousandsToK}} / {{boss.hp | goldRoundThousandsToK}}
|
||||
| {{Math.ceil(progress.hp) | roundLargeNumbers}} / {{boss.hp | roundLargeNumbers}}
|
||||
.meter-label(tooltip='Rage', ng-if='boss.rage')
|
||||
span.glyphicon.glyphicon-fire
|
||||
.meter.mana(ng-if='boss.rage',popover="{{::boss.rage.description()}}",popover-title="{{::boss.rage.title()}}",popover-trigger='mouseenter',popover-placement='right')
|
||||
.bar(style='width: {{Shared.percent(progress.rage, boss.rage.value)}}%;')
|
||||
span.meter-text.value
|
||||
| {{Math.ceil(progress.rage) | goldRoundThousandsToK}} / {{boss.rage.value | goldRoundThousandsToK}}
|
||||
| {{Math.ceil(progress.rage) | roundLargeNumbers}} / {{boss.rage.value | roundLargeNumbers}}
|
||||
div(ng-if='::Content.quests[group.quest.key].collect')
|
||||
div(class="quest_{{::group.quest.key}}")
|
||||
h4=env.t('collected') + ':'
|
||||
|
|
|
|||
|
|
@ -81,16 +81,29 @@ script(type='text/ng-template', id='partials/options.social.challenges.html')
|
|||
h4=env.t('membership')
|
||||
.radio
|
||||
label
|
||||
input(type='radio', name='search-participation-radio', ng-click='search._isMember = true')
|
||||
input(type='radio', name='search-participation-radio', ng-model='search._isMember', ng-value='true', ng-change='filterChallenges')
|
||||
=env.t('participating')
|
||||
.radio
|
||||
label
|
||||
input(type='radio', name='search-participation-radio', ng-click='search._isMember = false')
|
||||
input(type='radio', name='search-participation-radio', ng-model='search._isMember', ng-value='false', ng-change='filterChallenges')
|
||||
=env.t('notParticipating')
|
||||
.radio
|
||||
label
|
||||
input(type='radio', name='search-participation-radio', ng-click='search._isMember = undefined', checked='checked')
|
||||
input(type='radio', name='search-participation-radio', ng-model='search._isMember', value='either', ng-change='filterChallenges')
|
||||
=env.t('either')
|
||||
h4=env.t('challengedOwnedFilterHeader')
|
||||
.radio
|
||||
label
|
||||
input(type='radio', name='search-owner-radio', ng-model='search._isOwner', ng-value='true', ng-change='filterChallenges')
|
||||
=env.t('challengedOwnedFilter')
|
||||
.radio
|
||||
label
|
||||
input(type='radio', name='search-owner-radio', ng-model='search._isOwner', ng-value='false', ng-change='filterChallenges')
|
||||
=env.t('challengedNotOwnedFilter')
|
||||
.radio
|
||||
label
|
||||
input(type='radio', name='search-owner-radio', ng-model='search._isOwner', value='either', ng-change='filterChallenges', checked='checked')
|
||||
=env.t('challengedEitherOwnedFilter')
|
||||
.col-md-10
|
||||
a.btn.btn-info#back-to-challenges(ng-show="cid", ui-sref='options.social.challenges', ui-sref-opts='{reload: true}')
|
||||
| Back to all challenges
|
||||
|
|
|
|||
|
|
@ -146,8 +146,9 @@ nav.toolbar(ng-controller='AuthCtrl', ng-class='{active: isToolbarHidden}')
|
|||
a(target="_blank" ng-href='http://data.habitrpg.com?uuid={{user._id}}')=env.t('dataTool')
|
||||
li
|
||||
a(ui-sref='options.settings.export')=env.t('exportData')
|
||||
li.toolbar-button-dropdown
|
||||
li.toolbar-button-dropdown.highlight
|
||||
a(target="_blank" href='http://habitrpg.wikia.com/wiki/')
|
||||
span.glyphicon.glyphicon-question-sign
|
||||
span=env.t('help')
|
||||
a(ng-click='expandMenu("help")', ng-class='{active: _expandedMenu == "help"}')
|
||||
span ☰
|
||||
|
|
@ -169,7 +170,7 @@ nav.toolbar(ng-controller='AuthCtrl', ng-class='{active: isToolbarHidden}')
|
|||
a(ng-click='showTour()', popover-placement='right', popover-trigger='mouseenter', popover=env.t('restartTour'))= env.t('showTour')
|
||||
ul.toolbar-subscribe(ng-if='!user.purchased.plan.customerId')
|
||||
li.toolbar-subscribe-button
|
||||
button(ui-sref='options.settings.subscription',popover-trigger='mouseenter',popover-placement='bottom',popover-title=env.t('subscriptions'),popover=env.t('subDescription'),popover-append-to-body='true')=env.t('subscribe')
|
||||
button.highlight(ui-sref='options.settings.subscription',popover-trigger='mouseenter',popover-placement='bottom',popover-title=env.t('subscriptions'),popover=env.t('subDescription'),popover-append-to-body='true')=env.t('subscribe')
|
||||
ul.toolbar-options
|
||||
li.toolbar-notifs
|
||||
a(ng-click='expandMenu("notifs")')
|
||||
|
|
@ -264,7 +265,7 @@ nav.toolbar(ng-controller='AuthCtrl', ng-class='{active: isToolbarHidden}')
|
|||
span.gem-text {{user.balance * 4 | number:0}}
|
||||
li.toolbar-currency.gold(popover=env.t('gold') + ' ({{Shared.gold(user.stats.gp)}})', popover-placement='bottom',popover-trigger='mouseenter')
|
||||
span.shop_gold
|
||||
span {{Shared.gold(user.stats.gp) | goldRoundThousandsToK}}
|
||||
span {{Shared.gold(user.stats.gp) | roundLargeNumbers}}
|
||||
li.toolbar-currency.silver(popover=env.t('silver'), popover-placement='bottom',popover-trigger='mouseenter')
|
||||
span.shop_silver
|
||||
span {{Shared.silver(user.stats.gp)}}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,65 @@
|
|||
h5 6/1/2015 - NEW EQUIPMENT: THE ENCHANTED ARMOIRE, JUNE BACKGROUNDS, AND NEW MOUNT POSITIONING!
|
||||
h5 6/11/2015 - REPEATING TASKS, START DATE, AND MOBILE APP UPDATES!
|
||||
p
|
||||
br
|
||||
p.small.muted by Blade and fallenpanda
|
||||
hr
|
||||
tr
|
||||
td
|
||||
.promo_enchanted_armoire.pull-right
|
||||
h5 New Equipment: The Enchanted Armoire!
|
||||
p Now after you achieve Ultimate Gear, you'll unlock a new Reward: THE ENCHANTED ARMOIRE!
|
||||
h5 New Repeat Option for Dailies
|
||||
p Dailies now have a new Advanced Option: Repeat Every X Days. You've wanted this feature for a long time, and it's finally here!
|
||||
br
|
||||
p Click on the Enchanted Armoire, a 100 GP Reward in the Rewards Column, for a random chance at special Equipment! It may also give you random XP or food items. We'll be adding new equipment to it every month, but even when you've exhausted the current supply, you can keep clicking for a chance at food and XP.
|
||||
p First, please note that this new option is OPT-IN only. We won't make any changes to your preexisting Dailies without you knowing it. We wouldn't do that!
|
||||
br
|
||||
p Now go spend all that accumulated Gold! May the Random Number Generator smile upon you...
|
||||
p.small.muted by Lemoness and SabreCat
|
||||
p.small.muted Art by Kiwibot, Starsystemic, UncommonCriminal, Zoebeagle, and Andrews38
|
||||
p That being said, here are the new features:
|
||||
tr
|
||||
td
|
||||
.background_island_waterfalls.pull-right
|
||||
h5 June Backgrounds Revealed
|
||||
p There are three new avatar backgrounds in the <a href='/#/options/profile/backgrounds' target='_blank'>Background Shop</a>! Now your avatar can paddle a Drifting Raft, float through a sea of Shimmery Bubbles, or picnic near Island Waterfalls!
|
||||
p.small.muted by (in order): Teto is Great, beffymaroo, and UncommonCriminal
|
||||
h5 Repeating Tasks
|
||||
p Use the "Every X Days" function under Dailies Advanced Options to create tasks that repeat after a certain number of days have passed, whether every 2 days, every 15 days, every 30 days... You choose the number that works for you!
|
||||
br
|
||||
p These Dailies are only due on those given dates. Need to pay your rent every 30 days? Take medicine every other day? Water your plants every 4 days? No longer a problem.
|
||||
tr
|
||||
td
|
||||
h5 New Mount Positioning!
|
||||
p The mount positioning has been fixed for all the base mounts where it looked like the avatar was riding extreme sidesaddle. Now avatars sit properly, no longer clinging to the sides of their mounts for dear life.
|
||||
p.small.muted by Kiwibot, Lemoness, and SabreCat
|
||||
h5 Start Date
|
||||
p Dailies now have a Start Date. They will not be due before this date. This means that if you want to add a new Daily while you're thinking about it, but not have it be due until later, you can achieve that by setting a future Start Date!
|
||||
tr
|
||||
td
|
||||
h5 Mobile App Updates
|
||||
p New <a href='https://play.google.com/store/apps/details?id=com.ocdevel.habitrpg' target='_blank'>Android</a> and <a href='https://itunes.apple.com/us/app/habitrpg/id689569235?mt=8' target='_blank'>iOS</a> updates are available to support this feature. Please, update your apps before using it, or the new repeating Dailies will not display normally on the mobile apps!
|
||||
tr
|
||||
td
|
||||
h5 Other Notes
|
||||
p For a short period of time, the <a href='http://data.habitrpg.com' target='_blank'>Data Display Tool</a> will not be able to calculate damage correctly for Repeat Every X Dailies. We'll get that updated very soon so that it will be accurate again!
|
||||
br
|
||||
p If you still have questions about Repeat Every X Dailies, don't hesitate to ask in <a href='/#/options/groups/guilds/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>the Newbies Guild</a>!
|
||||
|
||||
hr
|
||||
a(href='/static/old-news', target='_blank') Read older news
|
||||
|
||||
mixin oldNews
|
||||
|
||||
h5 6/1/2015 - NEW EQUIPMENT: THE ENCHANTED ARMOIRE, JUNE BACKGROUNDS, AND NEW MOUNT POSITIONING!
|
||||
tr
|
||||
td
|
||||
.promo_enchanted_armoire.pull-right
|
||||
h5 New Equipment: The Enchanted Armoire!
|
||||
p Now after you achieve Ultimate Gear, you'll unlock a new Reward: THE ENCHANTED ARMOIRE!
|
||||
br
|
||||
p Click on the Enchanted Armoire, a 100 GP Reward in the Rewards Column, for a random chance at special Equipment! It may also give you random XP or food items. We'll be adding new equipment to it every month, but even when you've exhausted the current supply, you can keep clicking for a chance at food and XP.
|
||||
br
|
||||
p Now go spend all that accumulated Gold! May the Random Number Generator smile upon you...
|
||||
p.small.muted by Lemoness and SabreCat
|
||||
p.small.muted Art by Kiwibot, Starsystemic, UncommonCriminal, Zoebeagle, and Andrews38
|
||||
tr
|
||||
td
|
||||
.background_island_waterfalls.pull-right
|
||||
h5 June Backgrounds Revealed
|
||||
p There are three new avatar backgrounds in the <a href='/#/options/profile/backgrounds' target='_blank'>Background Shop</a>! Now your avatar can paddle a Drifting Raft, float through a sea of Shimmery Bubbles, or picnic near Island Waterfalls!
|
||||
p.small.muted by (in order): Teto is Great, beffymaroo, and UncommonCriminal
|
||||
tr
|
||||
td
|
||||
h5 New Mount Positioning!
|
||||
p The mount positioning has been fixed for all the base mounts where it looked like the avatar was riding extreme sidesaddle. Now avatars sit properly, no longer clinging to the sides of their mounts for dear life.
|
||||
p.small.muted by Kiwibot, Lemoness, and SabreCat
|
||||
h5 6/1/2015 - JUNE MYSTERY ITEM!
|
||||
tr
|
||||
td
|
||||
|
|
|
|||
70
website/views/shared/tasks/edit/advanced_options.jade
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
div(ng-if='::task.type!="reward"')
|
||||
button.advanced-options-toggle.option-title.mega(type='button',
|
||||
ng-click='task._advanced = !task._advanced', tooltip=env.t('expandCollapse'))
|
||||
=env.t('advancedOptions')
|
||||
|
||||
div(ng-show='task._advanced')
|
||||
div(ng-if='::task.type == "daily"')
|
||||
.form-group
|
||||
legend.option-title
|
||||
span.hint(popover-title=env.t('startDateHelpTitle'), popover=env.t("startDateHelp"), popover-trigger='mouseenter')
|
||||
=env.t('startDate')
|
||||
|
||||
input.form-control(type='text', ng-model='task.startDate',
|
||||
datepicker-popup='{{::user.preferences.dateFormat}}', is-open='datepickerOpened',
|
||||
ng-click='datepickerOpened = true', ng-disabled='task.challenge.id')
|
||||
|
||||
hr
|
||||
|
||||
.form-group
|
||||
legend.option-title=env.t('repeat')
|
||||
select.form-control(ng-model='task.frequency', ng-disabled='task.challenge.id')
|
||||
option(value='weekly')=env.t('repeatWeek')
|
||||
option(value='daily')=env.t('repeatDays')
|
||||
|
||||
include ./dailies/repeat_options
|
||||
|
||||
hr
|
||||
|
||||
fieldset.option-group.advanced-option(ng-show="task._advanced")
|
||||
|
||||
legend.option-title
|
||||
a.hint.priority-multiplier-help(href='http://habitrpg.wikia.com/wiki/Difficulty', target='_blank', popover-title=env.t('difficultyHelpTitle'), popover-trigger='mouseenter', popover=env.t('difficultyHelpContent'))=env.t('difficulty')
|
||||
ul.priority-multiplier
|
||||
li
|
||||
button(type='button', ng-class='{active: task.priority==1 || !task.priority}',
|
||||
ng-click='task.challenge.id || (task.priority=1)')
|
||||
=env.t('easy')
|
||||
li
|
||||
button(type='button', ng-class='{active: task.priority==1.5}',
|
||||
ng-click='task.challenge.id || (task.priority=1.5)')
|
||||
=env.t('medium')
|
||||
li
|
||||
button(type='button', ng-class='{active: task.priority==2}',
|
||||
ng-click='task.challenge.id || (task.priority=2)')
|
||||
=env.t('hard')
|
||||
|
||||
span(ng-if='task.type=="daily"')
|
||||
legend.option-title.pull-left=env.t('restoreStreak')
|
||||
input.option-content(type='number', ng-model='task.streak')
|
||||
|
||||
div(ng-if='::(user.preferences.allocationMode == "taskbased" && user.preferences.automaticAllocation) || $state.is("options.social.challenges")')
|
||||
legend.option-title.pull-left=env.t('attributes')
|
||||
ul.task-attributes
|
||||
li
|
||||
button(type='button', ng-class='{active: task.attribute=="str"}',
|
||||
ng-click='task.attribute="str"')
|
||||
=env.t('physical')
|
||||
li
|
||||
button(type='button', ng-class='{active: task.attribute=="int"}',
|
||||
ng-click='task.attribute="int"')
|
||||
=env.t('mental')
|
||||
li
|
||||
button(type='button', ng-class='{active: task.attribute=="con"}',
|
||||
ng-click='task.attribute="con"')
|
||||
=env.t('social')
|
||||
li
|
||||
button(type='button', ng-class='{active: task.attribute=="per"}',
|
||||
ng-click='task.attribute="per"',
|
||||
popover=env.t('otherExamples'), popover-trigger='mouseenter', popover-placement='top')
|
||||
=env.t('other')
|
||||
23
website/views/shared/tasks/edit/checklist.jade
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
.task-checklist-edit(ng-if='::!$state.includes("options.social.challenges") && (task.type=="daily" || task.type=="todo")')
|
||||
ul
|
||||
li
|
||||
button(type='button', ng-if='!task.checklist[0]'
|
||||
popover=env.t('checklistText'), popover-trigger='mouseenter', popover-placement='bottom',
|
||||
ng-click='addChecklist(task)')
|
||||
span.glyphicon.glyphicon-tasks
|
||||
span=env.t('addChecklist')
|
||||
|
||||
.checklist-form(ng-if='task.checklist')
|
||||
fieldset.option-group(ng-if='!$state.includes("options.social.challenges")')
|
||||
legend.option-title(ng-if='task.checklist[0]')
|
||||
span.hint(popover=env.t('checklistText'), popover-trigger='mouseenter', popover-placement='bottom')
|
||||
=env.t('checklist')
|
||||
ul(hrpg-sort-checklist)
|
||||
li(ng-repeat='item in task.checklist')
|
||||
//input(type='checkbox',ng-model='item.completed',ng-change='saveTask(task,true)')
|
||||
//-,ng-blur='saveTask(task,true)')
|
||||
span.checklist-icon.glyphicon.glyphicon-resize-vertical
|
||||
input(type='text', ng-model='item.text',
|
||||
ui-keyup="{'13':'addChecklistItem(task,$event,$index)','38 40':'navigateChecklist(task,$index,$event)'}")
|
||||
a(ng-click='removeChecklistItem(task,$event,$index,true)')
|
||||
span.glyphicon.glyphicon-trash(tooltip=env.t('delete'))
|
||||
3
website/views/shared/tasks/edit/dailies/calendar.jade
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fieldset.option-group.calendar(ng-if='::task.type=="daily"', class="option-group")
|
||||
.dailies
|
||||
include ./repeat_options
|
||||
25
website/views/shared/tasks/edit/dailies/repeat_options.jade
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
legend.option-title=env.t('repeatEvery')
|
||||
|
||||
// If frequency is daily
|
||||
ng-form.form-group(name='everyX' ng-if='task.frequency=="daily"')
|
||||
.input-group
|
||||
input.form-control(type='number', ng-model='task.everyX', ng-disabled='task.challenge.id', min='0', required)
|
||||
span.input-group-addon {{task.everyX == 1 ? env.t('day') : env.t('days')}}
|
||||
|
||||
// If frequency is weekly
|
||||
.form-group(ng-if='task.frequency=="weekly"')
|
||||
ul.repeat-days
|
||||
// note, does not use data-toggle="buttons-checkbox" - it would interfere with our own click binding
|
||||
mixin dayOfWeek(day, num)
|
||||
li
|
||||
button(type='button', ng-class='{active: task.repeat.#{day}}',
|
||||
ng-disabled='task.challenge.id', ng-click='task.repeat.#{day} = !task.repeat.#{day}')
|
||||
| {{::moment.weekdaysMin(#{num})}}
|
||||
|
||||
+dayOfWeek('su', 0)
|
||||
+dayOfWeek('m', 1)
|
||||
+dayOfWeek('t', 2)
|
||||
+dayOfWeek('w', 3)
|
||||
+dayOfWeek('th', 4)
|
||||
+dayOfWeek('f', 5)
|
||||
+dayOfWeek('s', 6)
|
||||
8
website/views/shared/tasks/edit/habits/plus_minus.jade
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fieldset.option-group.plusminus(ng-if='task.type=="habit" && !task.challenge.id')
|
||||
legend.option-title=env.t('direction/Actions')
|
||||
span.task-checker
|
||||
input.visuallyhidden.focusable(id='{{obj._id}}_{{task.id}}-option-plus', type='checkbox', ng-model='task.up')
|
||||
label(for='{{obj._id}}_{{task.id}}-option-plus')
|
||||
span.task-checker
|
||||
input.visuallyhidden.focusable(id='{{obj._id}}_{{task.id}}-option-minus', type='checkbox', ng-model='task.down')
|
||||
label(for='{{obj._id}}_{{task.id}}-option-minus')
|
||||
52
website/views/shared/tasks/edit/index.jade
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
div(ng-if='task._editing')
|
||||
.task-options
|
||||
|
||||
// Broken Challenge
|
||||
.well(ng-if='task.challenge.broken')
|
||||
div(ng-if='task.challenge.broken=="TASK_DELETED"')
|
||||
p=env.t('brokenTask')
|
||||
p
|
||||
a(ng-click='unlink(task, "keep")')=env.t('keepIt')
|
||||
|
|
||||
a(ng-click="removeTask(task, obj[list.type+'s'])")=env.t('removeIt')
|
||||
div(ng-if='task.challenge.broken=="CHALLENGE_DELETED"')
|
||||
p
|
||||
|
|
||||
=env.t('brokenChallenge')
|
||||
p
|
||||
a(ng-click='unlink(task, "keep-all")')=env.t('keepThem')
|
||||
| |
|
||||
a(ng-click='unlink(task, "remove-all")')=env.t('removeThem')
|
||||
div(ng-if='task.challenge.broken=="CHALLENGE_CLOSED"')
|
||||
p
|
||||
!=env.t('challengeCompleted', {user: "{{task.challenge.winner}}"})
|
||||
p
|
||||
a(ng-click='unlink(task, "keep-all")')=env.t('keepThem')
|
||||
| |
|
||||
a(ng-click='unlink(task, "remove-all")')=env.t('removeThem')
|
||||
//div(ng-if='task.challenge.broken=="UNSUBSCRIBED"')
|
||||
p=env.t('unsubChallenge')
|
||||
p
|
||||
a(ng-click="unlink(task, 'keep-all')")=env.t('keepThem')
|
||||
| |
|
||||
a(ng-click="unlink(task, 'remove-all')")=env.t('removeThem')
|
||||
|
||||
include ./checklist
|
||||
|
||||
form(ng-submit='saveTask(task,false,true)')
|
||||
include ./text_notes
|
||||
|
||||
include ./habits/plus_minus
|
||||
|
||||
include ./dailies/calendar
|
||||
|
||||
include ./rewards/pricing
|
||||
|
||||
include ./todos/due_date
|
||||
|
||||
include ./tags
|
||||
|
||||
include ./advanced_options
|
||||
|
||||
.save-close
|
||||
button(type='submit')=env.t('saveAndClose')
|
||||
5
website/views/shared/tasks/edit/rewards/pricing.jade
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
fieldset.option-group.option-short(ng-if='task.type=="reward" && !task.challenge.id')
|
||||
legend.option-title=env.t('price')
|
||||
input.option-content(type='number', size='16', min='0', step='any', ng-model='task.value', required)
|
||||
.money.input-suffix
|
||||
span.shop_gold
|
||||
5
website/views/shared/tasks/edit/tags.jade
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
fieldset.option-group(ng-if='!$state.includes("options.social.challenges")')
|
||||
p.option-title.mega(ng-click='task._tags = !task._tags', tooltip=env.t('expandCollapse'))=env.t('tags')
|
||||
label.checkbox(ng-repeat='tag in user.tags', ng-class="{visuallyhidden: task._tags}")
|
||||
input(type='checkbox', ng-model='task.tags[tag.id]')
|
||||
markdown(text='tag.name')
|
||||
7
website/views/shared/tasks/edit/text_notes.jade
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fieldset.option-group
|
||||
label.option-title=env.t('text')
|
||||
input.form-control(type='text', ng-model='task.text', required, ng-disabled='task.challenge.id')
|
||||
|
||||
fieldset.option-group
|
||||
label.option-title=env.t('extraNotes')
|
||||
textarea.form-control(rows='3', ng-model='task.notes', ng-model-options="{debounce: 1000}")
|
||||
6
website/views/shared/tasks/edit/todos/due_date.jade
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
fieldset.option-group(ng-if='task.type=="todo" && !task.challenge.id')
|
||||
legend.option-title=env.t('dueDate')
|
||||
input.option-content.datepicker(type='text', ng-model='task.date',
|
||||
datepicker-popup='{{::user.preferences.dateFormat}}', is-open='datepickerOpened',
|
||||
ng-click='datepickerOpened = true')
|
||||
|
||||
39
website/views/shared/tasks/index.jade
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Note here, we need this part of Habit to be a directive since we're going to be passing it variables from various
|
||||
// parts of the app. The alternative would be to create new scopes for different containing sections, but that
|
||||
// started to get unwieldy
|
||||
|
||||
include ./task_view/mixins
|
||||
script(id='templates/habitrpg-tasks.html', type="text/ng-template")
|
||||
.tasks-lists.container-fluid
|
||||
.row
|
||||
.col-md-3.col-sm-6(ng-repeat='list in lists', ng-class='::{"rewards-module": list.type==="reward"}')
|
||||
.task-column(class='{{::list.type}}s')
|
||||
|
||||
include ./task_view/graph
|
||||
|
||||
h2.task-column_title {{::list.header}}
|
||||
|
||||
include ./task_view/help
|
||||
|
||||
.todos-chart(ng-if='::list.type == "todo"', ng-show='charts.todos')
|
||||
|
||||
include ./task_view/add_new
|
||||
|
||||
alert.alert-warning.dailiesRestingInInn(ng-if='::list.type == "daily" && user.preferences.sleep')
|
||||
i.glyphicon.glyphicon-warning-sign
|
||||
=env.t('dailiesRestingInInn')
|
||||
|
||||
+taskColumnTabs('top')
|
||||
|
||||
// Actual List
|
||||
ul(class='{{::list.type}}s main-list', ng-show='obj[list.type + "s"].length > 0', hrpg-sort-tasks, ng-if='!$state.includes("options.social.challenges")')
|
||||
include ./task
|
||||
//Loads the non-sortable lists for challenges
|
||||
ul(class='{{::list.type}}s main-list', ng-show='obj[list.type + "s"].length > 0', ng-if='$state.includes("options.social.challenges")')
|
||||
include ./task
|
||||
|
||||
include ./task_view/static_rewards
|
||||
|
||||
include ./task_view/spells
|
||||
|
||||
+taskColumnTabs('bottom')
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
// Note here, we need this part of Habit to be a directive since we're going to be passing it variables from various
|
||||
// parts of the app. The alternative would be to create new scopes for different containing sections, but that
|
||||
// started to get unwieldy
|
||||
script(id='templates/habitrpg-tasks.html', type="text/ng-template")
|
||||
.tasks-lists.container-fluid
|
||||
.row
|
||||
.col-md-3.col-sm-6(bindonce='lists', ng-repeat='list in lists', ng-class='::{"rewards-module": list.type==="reward"}')
|
||||
.task-column(class='{{list.type}}s')
|
||||
|
||||
// Todos export/graph options
|
||||
span.option-box.pull-right(ng-if='::main')
|
||||
a.option-action(ng-if='list.type=="todo"', ng-show='obj.history.todos', ng-click='toggleChart("todos")', tooltip=env.t('progress'), style='margin-right:5px;')
|
||||
span.glyphicon.glyphicon-signal
|
||||
//a.option-action(ng-href='/v1/users/{{user.id}}/calendar.ics?apiToken={{user.apiToken}}', tooltip='iCal')
|
||||
//-a.option-action(ng-if='list.type=="todo"', ng-click='notPorted()', tooltip='iCal', ng-show='false')
|
||||
span.glyphicon.glyphicon-calendar
|
||||
// <a href="https://www.google.com/calendar/render?cid={{encodeiCalLink(_user.id, _user.apiToken)}}" rel=tooltip title="Google Calendar"><i class=icon-calendar></i></a>
|
||||
a.option-action(ng-click='list.help=!list.help', tooltip='Click for help')
|
||||
span.glyphicon.glyphicon-question-sign(style={'zoom':1.5,'vertical-align':'-webkit-baseline-middle'})
|
||||
|
||||
// Header
|
||||
h2.task-column_title
|
||||
| {{list.header}}
|
||||
|
||||
div(ng-if='list.help', ng-switch='::list.type')
|
||||
div(ng-switch-when='habit')
|
||||
ul
|
||||
li!=env.t('habitHelp1', {plusIcon:"<span class='glyphicon glyphicon-plus'></span>"})
|
||||
li!=env.t('habitHelp2', {minusIcon:"<span class='glyphicon glyphicon-minus'></span>"})
|
||||
li!=env.t('habitHelp3')
|
||||
li!=env.t('newbieGuild', {linkStart:"<a href='https://habitrpg.com/#/options/groups/guilds/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>", linkEnd: "</a>"})
|
||||
div(ng-switch-when='daily')
|
||||
ul
|
||||
li!=env.t('dailyHelp1', {emphasisStart:"<strong>", emphasisEnd:"</strong>", pencilIcon:"<span class='glyphicon glyphicon-pencil'></span>"})
|
||||
li=env.t('dailyHelp2')
|
||||
li!=env.t('dailyHelp3', {emphasisStart:"<strong>", emphasisEnd:"</strong>"})
|
||||
li!=env.t('dailyHelp4', {linkStart:"<a href='/#/options/settings/settings' target='_blank'>", linkEnd:"</a>"})
|
||||
li!=env.t('dailyHelp5')
|
||||
li!=env.t('newbieGuild', {linkStart:"<a href='https://habitrpg.com/#/options/groups/guilds/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>", linkEnd: "</a>"})
|
||||
div(ng-switch-when='todo')
|
||||
ul
|
||||
li=env.t('toDoHelp1')
|
||||
li=env.t('toDoHelp2')
|
||||
li=env.t('toDoHelp3')
|
||||
li!=env.t('toDoHelp4')
|
||||
li!=env.t('newbieGuild', {linkStart:"<a href='https://habitrpg.com/#/options/groups/guilds/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>", linkEnd: "</a>"})
|
||||
div(ng-switch-when='reward')
|
||||
ul
|
||||
li!=env.t('rewardHelp1', {linkStart:"<a href='/#/options/inventory/equipment' target='_blank'>", linkEnd: "</a>"})
|
||||
li!=env.t('rewardHelp2', {linkStart:"<a href='/#/options/profile/stats' target='_blank'>", linkEnd: "</a>"})
|
||||
li=env.t('rewardHelp3')
|
||||
li!=env.t('rewardHelp4')
|
||||
li!=env.t('newbieGuild', {linkStart:"<a href='https://habitrpg.com/#/options/groups/guilds/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>", linkEnd: "</a>"})
|
||||
|
||||
// Todo Chart
|
||||
.todos-chart(ng-if='::list.type == "todo"', ng-show='charts.todos')
|
||||
|
||||
// Add New
|
||||
form.task-add(name='new{{list.type}}form', ng-hide='obj._locked', ng-submit='addTask(obj[list.type+"s"],list)' novalidate)
|
||||
textarea(rows='6', task-focus='list.bulk && list.focus', ng-model='list.newTask', placeholder='{{list.placeHolderBulk}}', ng-if='list.bulk', ui-keydown='{"meta-enter ctrl-enter":"addTask(obj[list.type+\'s\'],list)"}', required)
|
||||
input(type='text', task-focus='!list.bulk && list.focus', ng-model='list.newTask', placeholder='{{list.placeHolder}}', ng-if='!list.bulk', required)
|
||||
button(type='submit', ng-disabled='new{{list.type}}form.$invalid')
|
||||
div.empty-task-notification( ng-show='new{{list.type}}form.$invalid', tooltip=env.t("emptyTask") )
|
||||
span.glyphicon.glyphicon-plus
|
||||
span.glyphicon.glyphicon-plus(ng-show='!new{{list.type}}form.$invalid')
|
||||
small.help-block.btn-link.pull-right(ng-click='toggleBulk(list)')
|
||||
span(ng-if='!list.bulk')=env.t('addmultiple')
|
||||
span(ng-if='list.bulk')=env.t('addsingle')
|
||||
|
||||
alert.alert-warning.dailiesRestingInInn(ng-if='::list.type == "daily" && user.preferences.sleep')
|
||||
i.glyphicon.glyphicon-warning-sign
|
||||
=env.t('dailiesRestingInInn')
|
||||
|
||||
mixin taskColumnTabs(position)
|
||||
// Habits Tabs
|
||||
div(ng-if='::main && list.type=="habit"', class='tabbable tabs-below')
|
||||
ul.task-filter
|
||||
li(ng-class='{active: list.view == "all"}')
|
||||
a(ng-click='list.view = "all"')=env.t('all')
|
||||
li(ng-class='{active: list.view == "yellowred"}')
|
||||
a(ng-click='list.view = "yellowred"')=env.t('yellowred')
|
||||
li(ng-class='{active: list.view == "greenblue"}')
|
||||
a(ng-click='list.view = "greenblue"')=env.t('greenblue')
|
||||
// Daily Tabs
|
||||
div(ng-if='::main && list.type=="daily"', class='tabbable tabs-below')
|
||||
// remaining/completed tabs
|
||||
ul.task-filter
|
||||
li(ng-class='{active: list.view == "all"}')
|
||||
a(ng-click='list.view = "all"')=env.t('all')
|
||||
li(ng-class='{active: list.view == "remaining"}')
|
||||
a(ng-click='list.view = "remaining"')=env.t('due')
|
||||
li(ng-class='{active: list.view == "complete"}')
|
||||
a(ng-click='list.view = "complete"')=env.t('grey')
|
||||
// Todo Tabs
|
||||
div(ng-if='::main && list.type=="todo"', ng-class='::{"tabbable tabs-below": list.type=="todo"}')
|
||||
if position=="bottom"
|
||||
div(ng-show='list.view == "complete"')
|
||||
.alert
|
||||
=env.t('lotOfToDos')
|
||||
button.task-action-btn.tile.spacious.bright(ng-click='user.ops.clearCompleted({})',popover=env.t('deleteToDosExplanation'),popover-trigger='mouseenter')=env.t('clearCompleted')
|
||||
p!=env.t('beeminderDeleteWarning')
|
||||
// remaining/completed tabs
|
||||
ul.task-filter
|
||||
li(ng-class='{active: list.view == "remaining"}')
|
||||
a(ng-click='list.view = "remaining"')=env.t('remaining')
|
||||
li(ng-class='{active: list.view == "dated"}')
|
||||
a(ng-click='list.view = "dated"')=env.t('dated')
|
||||
li(ng-class='{active: list.view == "complete"}')
|
||||
a(ng-click='list.view = "complete"')=env.t('complete')
|
||||
// Rewards Tabs
|
||||
div(ng-if='::main && list.type=="reward"', class='tabbable tabs-below')
|
||||
ul.task-filter
|
||||
li(ng-class='{active: list.view == "all"}')
|
||||
a(ng-click='list.view = "all"')=env.t('all')
|
||||
li(ng-class='{active: list.view == "ingamerewards"}')
|
||||
a(ng-click='list.view = "ingamerewards"')=env.t('ingamerewards')
|
||||
|
||||
+taskColumnTabs('top')
|
||||
|
||||
// Actual List
|
||||
ul(class='{{list.type}}s main-list', ng-show='obj[list.type + "s"].length > 0', hrpg-sort-tasks, ng-if='!$state.includes("options.social.challenges")')
|
||||
include ./task
|
||||
//Loads the non-sortable lists for challenges
|
||||
ul(class='{{list.type}}s main-list', ng-show='obj[list.type + "s"].length > 0', ng-if='$state.includes("options.social.challenges")')
|
||||
include ./task
|
||||
|
||||
// Static Rewards
|
||||
ul.items.rewards(ng-if='main && list.type=="reward"')
|
||||
li.task.reward-item(ng-repeat='item in itemStore',popover-trigger='mouseenter', popover-placement='top', popover='{{item.key == "armoire" && !user.flags.armoireEmpty ? env.t("armoireNotesFull") + armoireCount(user.items.gear.owned) : item.notes()}}')
|
||||
// right-hand side control buttons
|
||||
.task-meta-controls
|
||||
span.task-notes
|
||||
span.glyphicon.glyphicon-comment
|
||||
//left-hand size commands
|
||||
.task-controls.task-primary
|
||||
a.money.btn-buy.item-btn(ng-class='{highValue: item.value >= 1000}', ng-click='buy(item)')
|
||||
span.shop_gold
|
||||
span.reward-cost {{item.value}}
|
||||
// main content
|
||||
span(ng-class='::{"shop_{{item.key}} shop-sprite item-img": true}').reward-img
|
||||
p.task-text {{item.text()}}
|
||||
|
||||
// Events
|
||||
ul.items.rewards(ng-if='main && list.type=="reward" && (user.items.special.snowball>0 || user.stats.buffs.snowball || user.items.special.spookDust>0 || user.stats.buffs.spookDust || user.items.special.shinySeed>0 || user.stats.buffs.shinySeed)')
|
||||
|
||||
mixin specialSpell(k,canceler)
|
||||
li.task.reward-item(ng-if='#{canceler ? "user.stats.buffs."+canceler : "user.items.special."+k+">0"}',popover-trigger='mouseenter', popover-placement='top', popover='{{Content.spells.special.#{k}.notes()}}')
|
||||
.task-meta-controls
|
||||
span.task-notes
|
||||
span.glyphicon.glyphicon-comment
|
||||
//left-hand size commands
|
||||
.task-controls.task-primary
|
||||
a.money.btn-buy.item-btn(ng-click='castStart(Content.spells.special.#{k})', ng-class='{active: Content.spells.special.#{k}.key == spell.key}')
|
||||
if canceler
|
||||
span.shop_gold
|
||||
span.reward-cost {{Content.spells.special.#{k}.value}}
|
||||
else
|
||||
span.shop_spell(class='shop_#{k}')
|
||||
span.reward-cost {{user.items.special.#{k}}}
|
||||
// main content
|
||||
p.task-text {{Content.spells.special.#{k}.text()}}
|
||||
|
||||
+specialSpell('snowball')
|
||||
+specialSpell('spookDust')
|
||||
+specialSpell('shinySeed')
|
||||
+specialSpell('salt','snowball')
|
||||
+specialSpell('opaquePotion','spookDust')
|
||||
+specialSpell('petalFreePotion','shinySeed')
|
||||
|
||||
// Spells
|
||||
ul.items(ng-if='main && list.type=="reward" && user.stats.class && !user.preferences.disableClasses')
|
||||
li.task.reward-item(ng-repeat='(k,skill) in Content.spells[user.stats.class]', ng-if='user.stats.lvl >= skill.lvl',popover-trigger='mouseenter', popover-placement='top', popover='{{skill.notes()}}')
|
||||
.task-meta-controls
|
||||
span.task-notes
|
||||
span.glyphicon.glyphicon-comment
|
||||
//left-hand size commands
|
||||
.task-controls.task-primary
|
||||
a.money.btn-buy.item-btn(ng-click='castStart(skill)', ng-class='{active: skill.key == spell.key}')
|
||||
span.reward-cost
|
||||
strong {{skill.mana}}
|
||||
=env.t('mp')
|
||||
// main content
|
||||
span(ng-class='{"shop_{{skill.key}} shop-sprite item-img": true}')
|
||||
p.task-text {{skill.text()}}
|
||||
|
||||
br
|
||||
|
||||
+taskColumnTabs('bottom')
|
||||
56
website/views/shared/tasks/meta_controls.jade
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
.task-meta-controls
|
||||
|
||||
// Due Date
|
||||
span(ng-if='task.type=="todo" && task.date')
|
||||
span(ng-class='{"label label-danger":(moment(task.date).isBefore(_today, "days") && !task.completed)}') {{task.date | date:(user.preferences.dateFormat.indexOf('yyyy') == 0 ? user.preferences.dateFormat.substr(5) : user.preferences.dateFormat.substr(0,5))}}
|
||||
|
||||
// Streak
|
||||
|
|
||||
span(ng-show='task.streak') {{task.streak}}
|
||||
span(tooltip=env.t('streakCounter'))
|
||||
span.glyphicon.glyphicon-forward
|
||||
|
|
||||
|
||||
// Icons only available if you own the tasks (aka, hidden from challenge stats)
|
||||
span(ng-if='!obj._locked')
|
||||
a(ng-click='pushTask(task,$index,"top")', tooltip=env.t('pushTaskToTop'))
|
||||
span.glyphicon.glyphicon-open
|
||||
// a(ng-click='pushTask(task,$index,"bottom")', tooltip=env.t('pushTaskToBottom'))
|
||||
// span.glyphicon.glyphicon-import
|
||||
// // glyphicon-import or glyphicon-save or glyphicon-sort-by-attributes
|
||||
a.badge(ng-if='task.checklist[0]', ng-class='{"badge-success":checklistCompletion(task.checklist) == task.checklist.length}', ng-click='collapseChecklist(task)', tooltip=env.t('expandCollapse'))
|
||||
|{{checklistCompletion(task.checklist)}}/{{task.checklist.length}}
|
||||
span.glyphicon.glyphicon-tags(tooltip='{{Shared.appliedTags(user.tags, task.tags)}}', ng-hide='Shared.noTags(task.tags)')
|
||||
// edit
|
||||
a(ng-hide='task._editing', ng-click='editTask(task)', tooltip=env.t('edit'))
|
||||
|
|
||||
span.glyphicon.glyphicon-pencil(ng-hide='task._editing')
|
||||
|
|
||||
a(ng-hide='!task._editing', ng-click='editTask(task)', tooltip=env.t('cancel'))
|
||||
span.glyphicon.glyphicon-remove(ng-hide='!task._editing')
|
||||
|
|
||||
// save
|
||||
a(ng-hide='!task._editing', ng-click='editTask(task);saveTask(task)', tooltip=env.t('save'))
|
||||
span.glyphicon.glyphicon-ok(ng-hide='!task._editing')
|
||||
|
|
||||
//challenges
|
||||
span(ng-if='task.challenge.id')
|
||||
span(ng-if='task.challenge.broken')
|
||||
span.glyphicon.glyphicon-bullhorn(style='background-color:red;', ng-click='task._editing = true', tooltip=env.t('brokenChaLink') tooltip-placement='right')
|
||||
|
|
||||
span(ng-if='!task.challenge.broken')
|
||||
span.glyphicon.glyphicon-bullhorn(tooltip=env.t('challenge'))
|
||||
|
|
||||
// delete
|
||||
a(ng-if='!task.challenge.id', ng-click='removeTask(task, obj[list.type+"s"])', tooltip=env.t('delete'))
|
||||
span.glyphicon.glyphicon-trash
|
||||
|
|
||||
|
||||
// chart
|
||||
a(ng-show='task.history', ng-click='toggleChart(obj._id+task.id, task)', tooltip=env.t('progress'))
|
||||
span.glyphicon.glyphicon-signal
|
||||
|
|
||||
// notes
|
||||
span.task-notes(ng-show='task.notes && !task._editing', ng-click='task.popoverOpen = !task.popoverOpen', popover-trigger='click', data-popover-html="{{task.notes | markdown}}", popover-placement="top", popover-append-to-body='{{::modal ? "false":"true"}}')
|
||||
span.glyphicon.glyphicon-comment
|
||||
|
|
||||
|
|
@ -1,241 +1,17 @@
|
|||
li(bindonce='list', id='task-{{::task.id}}', ng-repeat='task in obj[list.type+"s"] | conditionalOrderBy: list.view=="dated":"date"', class='task {{Shared.taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main)}}', ng-click='spell && (list.type != "reward") && castEnd(task, "task", $event)', ng-class='{"cast-target":spell && (list.type != "reward"), "locked-task":obj._locked === true}', popover-trigger='mouseenter', data-popover-html="{{task.popoverOpen ? '' : task.notes | markdown}}", popover-placement="top", popover-append-to-body='{{::modal ? "false":"true"}}', ng-show='shouldShow(task, list, user.preferences)')
|
||||
// right-hand side control buttons
|
||||
.task-meta-controls
|
||||
li(id='task-{{::task.id}}',
|
||||
ng-repeat='task in obj[list.type+"s"] | filterByTextAndNotes: obj.filterQuery | conditionalOrderBy: list.view=="dated":"date"',
|
||||
class='task {{Shared.taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main)}}',
|
||||
ng-class='{"cast-target":spell && (list.type != "reward"), "locked-task":obj._locked === true}',
|
||||
ng-click='spell && (list.type != "reward") && castEnd(task, "task", $event)',
|
||||
ng-show='shouldShow(task, list, user.preferences)',
|
||||
popover-trigger='mouseenter', popover-placement="top", popover-append-to-body='{{::modal ? "false":"true"}}',
|
||||
data-popover-html="{{task.popoverOpen ? '' : task.notes | markdown}}")
|
||||
|
||||
// Due Date
|
||||
span(ng-if='task.type=="todo" && task.date')
|
||||
span(ng-class='{"label label-danger":(moment(task.date).isBefore(_today, "days") && !task.completed)}') {{task.date | date:(user.preferences.dateFormat.indexOf('yyyy') == 0 ? user.preferences.dateFormat.substr(5) : user.preferences.dateFormat.substr(0,5))}}
|
||||
ng-form(name='taskForm')
|
||||
include ./meta_controls
|
||||
|
||||
// Streak
|
||||
|
|
||||
span(ng-show='task.streak') {{task.streak}}
|
||||
span(tooltip=env.t('streakCounter'))
|
||||
span.glyphicon.glyphicon-forward
|
||||
|
|
||||
include ./task_view/index
|
||||
|
||||
// Icons only available if you own the tasks (aka, hidden from challenge stats)
|
||||
span(ng-if='!obj._locked')
|
||||
a(ng-click='pushTask(task,$index,"top")', tooltip=env.t('pushTaskToTop'))
|
||||
span.glyphicon.glyphicon-open
|
||||
// a(ng-click='pushTask(task,$index,"bottom")', tooltip=env.t('pushTaskToBottom'))
|
||||
// span.glyphicon.glyphicon-import
|
||||
// // glyphicon-import or glyphicon-save or glyphicon-sort-by-attributes
|
||||
a.badge(ng-if='task.checklist[0]', ng-class='{"badge-success":checklistCompletion(task.checklist) == task.checklist.length}', ng-click='collapseChecklist(task)', tooltip=env.t('expandCollapse'))
|
||||
|{{checklistCompletion(task.checklist)}}/{{task.checklist.length}}
|
||||
span.glyphicon.glyphicon-tags(tooltip='{{Shared.appliedTags(user.tags, task.tags)}}', ng-hide='Shared.noTags(task.tags)')
|
||||
// edit
|
||||
a(ng-hide='task._editing', ng-click='editTask(task)', tooltip=env.t('edit'))
|
||||
|
|
||||
span.glyphicon.glyphicon-pencil(ng-hide='task._editing')
|
||||
|
|
||||
a(ng-hide='!task._editing', ng-click='editTask(task)', tooltip=env.t('cancel'))
|
||||
span.glyphicon.glyphicon-remove(ng-hide='!task._editing')
|
||||
|
|
||||
// save
|
||||
a(ng-hide='!task._editing', ng-click='editTask(task);saveTask(task)', tooltip=env.t('save'))
|
||||
span.glyphicon.glyphicon-ok(ng-hide='!task._editing')
|
||||
|
|
||||
//challenges
|
||||
span(ng-if='task.challenge.id')
|
||||
span(ng-if='task.challenge.broken')
|
||||
span.glyphicon.glyphicon-bullhorn(style='background-color:red;', ng-click='task._editing = true', tooltip=env.t('brokenChaLink') tooltip-placement='right')
|
||||
|
|
||||
span(ng-if='!task.challenge.broken')
|
||||
span.glyphicon.glyphicon-bullhorn(tooltip=env.t('challenge'))
|
||||
|
|
||||
// delete
|
||||
a(ng-if='!task.challenge.id', ng-click='removeTask(task, obj[list.type+"s"])', tooltip=env.t('delete'))
|
||||
span.glyphicon.glyphicon-trash
|
||||
|
|
||||
|
||||
// chart
|
||||
a(ng-show='task.history', ng-click='toggleChart(obj._id+task.id, task)', tooltip=env.t('progress'))
|
||||
span.glyphicon.glyphicon-signal
|
||||
|
|
||||
// notes
|
||||
span.task-notes(ng-show='task.notes && !task._editing', ng-click='task.popoverOpen = !task.popoverOpen', popover-trigger='click', data-popover-html="{{task.notes | markdown}}", popover-placement="top", popover-append-to-body='{{::modal ? "false":"true"}}')
|
||||
span.glyphicon.glyphicon-comment
|
||||
|
|
||||
|
||||
// left-hand side checkbox
|
||||
.task-controls.task-primary(ng-if='!task._editing')
|
||||
|
||||
// Habits
|
||||
.task-actions(ng-if='::task.type=="habit"')
|
||||
// score() is overridden in challengesCtrl to do nothing
|
||||
a(ng-if='task.up', ng-click='applyingAction || score(task,"up")')
|
||||
span.glyphicon.glyphicon-plus
|
||||
a(ng-if='task.down', ng-click='applyingAction || score(task,"down")')
|
||||
span.glyphicon.glyphicon-minus
|
||||
|
||||
// Rewards
|
||||
span(ng-show='task.type=="reward"')
|
||||
a.money.btn-buy(ng-class='{highValue: task.value >= 1000}', ng-click='score(task, "down")')
|
||||
span.shop_gold
|
||||
span.reward-cost {{task.value}}
|
||||
// Daily & Todos
|
||||
span.task-checker.action-yesno(ng-if='::task.type=="daily" || task.type=="todo"')
|
||||
input.visuallyhidden.focusable(ng-if='$state.includes("tasks")', id='box-{{obj._id}}_{{task.id}}', type='checkbox', ng-model='task.completed', ng-change='task.type=="todo" && pushTask(task,$index,"bottom"); changeCheck(task)')
|
||||
input.visuallyhidden.focusable(ng-if='!$state.includes("tasks")', id='box-{{obj._id}}_{{task.id}}', type='checkbox')
|
||||
label(for='box-{{obj._id}}_{{task.id}}')
|
||||
|
||||
// main content
|
||||
div.task-text(ng-dblclick='task._editing ? saveTask(task) : editTask(task)')
|
||||
markdown(text='task.text',target='_blank')
|
||||
//-| {{task.text}}
|
||||
|
||||
div(ng-if='task.checklist && !$state.includes("options.social.challenges") && !task.collapseChecklist && !task._editing')
|
||||
fieldset.option-group.task-checklist
|
||||
label.checkbox(ng-repeat='item in task.checklist')
|
||||
input(type='checkbox',ng-model='item.completed',ng-change='saveTask(task,true)')
|
||||
markdown(text='item.text',target='_blank')
|
||||
|
||||
// edit/options dialog
|
||||
div(ng-if='task._editing')
|
||||
.task-options
|
||||
|
||||
// Broken Challenge
|
||||
.well(ng-if='task.challenge.broken')
|
||||
div(ng-if='task.challenge.broken=="TASK_DELETED"')
|
||||
p=env.t('brokenTask')
|
||||
p
|
||||
a(ng-click='unlink(task, "keep")')=env.t('keepIt')
|
||||
|
|
||||
a(ng-click="removeTask(task, obj[list.type+'s'])")=env.t('removeIt')
|
||||
div(ng-if='task.challenge.broken=="CHALLENGE_DELETED"')
|
||||
p
|
||||
|
|
||||
=env.t('brokenChallenge')
|
||||
p
|
||||
a(ng-click='unlink(task, "keep-all")')=env.t('keepThem')
|
||||
| |
|
||||
a(ng-click='unlink(task, "remove-all")')=env.t('removeThem')
|
||||
div(ng-if='task.challenge.broken=="CHALLENGE_CLOSED"')
|
||||
p
|
||||
!=env.t('challengeCompleted', {user: "{{task.challenge.winner}}"})
|
||||
p
|
||||
a(ng-click='unlink(task, "keep-all")')=env.t('keepThem')
|
||||
| |
|
||||
a(ng-click='unlink(task, "remove-all")')=env.t('removeThem')
|
||||
//div(ng-if='task.challenge.broken=="UNSUBSCRIBED"')
|
||||
p=env.t('unsubChallenge')
|
||||
p
|
||||
a(ng-click="unlink(task, 'keep-all')")=env.t('keepThem')
|
||||
| |
|
||||
a(ng-click="unlink(task, 'remove-all')")=env.t('removeThem')
|
||||
|
||||
|
||||
form(ng-submit='saveTask(task,false,true)')
|
||||
// Title text input
|
||||
label.option-title=env.t('title')
|
||||
input.option-content(type='text', ng-model='task.text', required, ng-disabled='task.challenge.id')
|
||||
|
||||
// Checklists
|
||||
.task-checklist-edit(ng-if='!$state.includes("options.social.challenges")')
|
||||
ul
|
||||
li
|
||||
button(type='button', ng-if='!task.checklist[0] && (task.type=="daily" || task.type=="todo")',ng-click='addChecklist(task)')
|
||||
span.glyphicon.glyphicon-tasks
|
||||
span=env.t('addChecklist')
|
||||
form.checklist-form(ng-if='task.checklist')
|
||||
fieldset.option-group(ng-if='!$state.includes("options.social.challenges")')
|
||||
legend.option-title
|
||||
span.hint(popover=env.t('checklistText'),popover-trigger='mouseenter',popover-placement='bottom')=env.t('checklist')
|
||||
ul(hrpg-sort-checklist)
|
||||
li(ng-repeat='item in task.checklist')
|
||||
//input(type='checkbox',ng-model='item.completed',ng-change='saveTask(task,true)')
|
||||
//-,ng-blur='saveTask(task,true)')
|
||||
span.checklist-icon.glyphicon.glyphicon-resize-vertical()
|
||||
input(type='text',ng-model='item.text', ui-keyup="{'13':'addChecklistItem(task,$event,$index)','38 40':'navigateChecklist(task,$index,$event)'}")
|
||||
a(ng-click='removeChecklistItem(task,$event,$index,true)')
|
||||
span.glyphicon.glyphicon-trash(tooltip=env.t('delete'))
|
||||
|
||||
form(ng-submit='saveTask(task,false,true)')
|
||||
// Notes text input
|
||||
fieldset.option-group
|
||||
label.option-title=env.t('extraNotes')
|
||||
textarea.option-content(rows='3', ng-model='task.notes', ng-model-options="{debounce: 1000}")
|
||||
|
||||
// if Habit, plus/minus command options
|
||||
fieldset.option-group.plusminus(ng-if='task.type=="habit" && !task.challenge.id')
|
||||
legend.option-title=env.t('direction/Actions')
|
||||
span.task-checker
|
||||
input.visuallyhidden.focusable(id='{{obj._id}}_{{task.id}}-option-plus', type='checkbox', ng-model='task.up')
|
||||
label(for='{{obj._id}}_{{task.id}}-option-plus')
|
||||
span.task-checker
|
||||
input.visuallyhidden.focusable(id='{{obj._id}}_{{task.id}}-option-minus', type='checkbox', ng-model='task.down')
|
||||
label(for='{{obj._id}}_{{task.id}}-option-minus')
|
||||
|
||||
// if Daily, calendar
|
||||
fieldset(ng-if='::task.type=="daily"', class="option-group")
|
||||
legend.option-title=env.t('repeat')
|
||||
ul.repeat-days(bindonce)
|
||||
// note, does not use data-toggle="buttons-checkbox" - it would interfere with our own click binding
|
||||
li
|
||||
button(ng-class='{active: task.repeat.su}', type='button', ng-click='task.challenge.id || (task.repeat.su = !task.repeat.su)') {{::moment.weekdaysMin(0)}}
|
||||
li
|
||||
button(ng-class='{active: task.repeat.m}', type='button', ng-click='task.challenge.id || (task.repeat.m = !task.repeat.m)') {{::moment.weekdaysMin(1)}}
|
||||
li
|
||||
button(ng-class='{active: task.repeat.t}', type='button', ng-click='task.challenge.id || (task.repeat.t = !task.repeat.t)') {{::moment.weekdaysMin(2)}}
|
||||
li
|
||||
button(ng-class='{active: task.repeat.w}', type='button', ng-click='task.challenge.id || (task.repeat.w = !task.repeat.w)') {{::moment.weekdaysMin(3)}}
|
||||
li
|
||||
button(ng-class='{active: task.repeat.th}', type='button', ng-click='task.challenge.id || (task.repeat.th = !task.repeat.th)') {{::moment.weekdaysMin(4)}}
|
||||
li
|
||||
button(ng-class='{active: task.repeat.f}', type='button', ng-click='task.challenge.id || (task.repeat.f= !task.repeat.f)') {{::moment.weekdaysMin(5)}}
|
||||
li
|
||||
button(ng-class='{active: task.repeat.s}', type='button', ng-click='task.challenge.id || (task.repeat.s = !task.repeat.s)') {{::moment.weekdaysMin(6)}}
|
||||
|
||||
// if Reward, pricing
|
||||
fieldset.option-group.option-short(ng-if='task.type=="reward" && !task.challenge.id')
|
||||
legend.option-title=env.t('price')
|
||||
input.option-content(type='number', size='16', min='0', step="any", ng-model='task.value')
|
||||
.money.input-suffix
|
||||
span.shop_gold
|
||||
|
||||
// if Todos, the due date
|
||||
fieldset.option-group(ng-if='task.type=="todo" && !task.challenge.id')
|
||||
legend.option-title=env.t('dueDate')
|
||||
input.option-content.datepicker(type='text', datepicker-popup='{{user.preferences.dateFormat}}', ng-model='task.date', is-open='datepickerOpened', ng-click='datepickerOpened = true')
|
||||
|
||||
// Tags
|
||||
fieldset.option-group(ng-if='!$state.includes("options.social.challenges")')
|
||||
p.option-title.mega(ng-click='task._tags = !task._tags', tooltip=env.t('expandCollapse'))=env.t('tags')
|
||||
label.checkbox(ng-repeat='tag in user.tags', ng-class="{visuallyhidden: task._tags}")
|
||||
input(type='checkbox', ng-model='task.tags[tag.id]')
|
||||
markdown(text='tag.name')
|
||||
|
||||
// Advanced Options
|
||||
span(ng-if='::task.type!="reward"')
|
||||
p.option-title.mega(ng-click='task._advanced = !task._advanced', tooltip=env.t('expandCollapse'))=env.t('advancedOptions')
|
||||
fieldset.option-group.advanced-option(ng-class="{visuallyhidden: task._advanced}")
|
||||
legend.option-title
|
||||
a.hint.priority-multiplier-help(href='http://habitrpg.wikia.com/wiki/Difficulty', target='_blank', popover-title=env.t('difficultyHelpTitle'), popover-trigger='mouseenter', popover=env.t('difficultyHelpContent'))=env.t('difficulty')
|
||||
ul.priority-multiplier
|
||||
li
|
||||
button(type='button', ng-class='{active: task.priority==1 || !task.priority}', ng-click='task.challenge.id || (task.priority=1)')=env.t('easy')
|
||||
li
|
||||
button(type='button', ng-class='{active: task.priority==1.5}', ng-click='task.challenge.id || (task.priority=1.5)')=env.t('medium')
|
||||
li
|
||||
button(type='button', ng-class='{active: task.priority==2}', ng-click='task.challenge.id || (task.priority=2)')=env.t('hard')
|
||||
//span(ng-if='task.type=="daily" && !task.challenge.id')
|
||||
span(ng-if='task.type=="daily"')
|
||||
legend.option-title.pull-left=env.t('restoreStreak')
|
||||
input.option-content(type='number', ng-model='task.streak')
|
||||
|
||||
div(ng-if='(user.preferences.allocationMode == "taskbased" && user.preferences.automaticAllocation) || $state.is("options.social.challenges")')
|
||||
legend.option-title.pull-left=env.t('attributes')
|
||||
ul.task-attributes
|
||||
li
|
||||
button(type='button', ng-class='{active: task.attribute=="str"}', ng-click='task.attribute="str"')=env.t('physical')
|
||||
li
|
||||
button(type='button', ng-class='{active: task.attribute=="int"}', ng-click='task.attribute="int"')=env.t('mental')
|
||||
li
|
||||
button(type='button', ng-class='{active: task.attribute=="con"}', ng-click='task.attribute="con"')=env.t('social')
|
||||
li
|
||||
button(type='button', ng-class='{active: task.attribute=="per"}', ng-click='task.attribute="per"', popover=env.t('otherExamples'), popover-trigger='mouseenter', popover-placement='top')=env.t('other')
|
||||
|
||||
.save-close
|
||||
button(type='submit')=env.t('saveAndClose')
|
||||
include ./edit/index
|
||||
|
||||
div(class='{{obj._id}}{{task.id}}-chart', ng-show='charts[obj._id+task.id]')
|
||||
|
|
|
|||
10
website/views/shared/tasks/task_view/add_new.jade
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
form.task-add(name='new{{list.type}}form', ng-hide='obj._locked', ng-submit='addTask(obj[list.type+"s"],list)', novalidate)
|
||||
textarea(rows='6', task-focus='list.bulk && list.focus', ng-model='list.newTask', placeholder='{{list.placeHolderBulk}}', ng-if='list.bulk', ui-keydown='{"meta-enter ctrl-enter":"addTask(obj[list.type+\'s\'],list)"}', required)
|
||||
input(type='text', task-focus='!list.bulk && list.focus', ng-model='list.newTask', placeholder='{{list.placeHolder}}', ng-if='!list.bulk', required)
|
||||
button(type='submit', ng-disabled='new{{list.type}}form.$invalid')
|
||||
div.empty-task-notification( ng-show='new{{list.type}}form.$invalid', tooltip=env.t("emptyTask") )
|
||||
span.glyphicon.glyphicon-plus
|
||||
span.glyphicon.glyphicon-plus(ng-show='!new{{list.type}}form.$invalid')
|
||||
small.help-block.btn-link.pull-right(ng-click='toggleBulk(list)')
|
||||
span(ng-if='!list.bulk')=env.t('addmultiple')
|
||||
span(ng-if='list.bulk')=env.t('addsingle')
|
||||
9
website/views/shared/tasks/task_view/graph.jade
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
span.option-box.pull-right(ng-if='::main')
|
||||
a.option-action(ng-if='list.type=="todo"', ng-show='obj.history.todos', ng-click='toggleChart("todos")', tooltip=env.t('progress'), style='margin-right:5px;')
|
||||
span.glyphicon.glyphicon-signal
|
||||
//a.option-action(ng-href='/v1/users/{{user.id}}/calendar.ics?apiToken={{user.apiToken}}', tooltip='iCal')
|
||||
//-a.option-action(ng-if='list.type=="todo"', ng-click='notPorted()', tooltip='iCal', ng-show='false')
|
||||
span.glyphicon.glyphicon-calendar
|
||||
// <a href="https://www.google.com/calendar/render?cid={{encodeiCalLink(_user.id, _user.apiToken)}}" rel=tooltip title="Google Calendar"><i class=icon-calendar></i></a>
|
||||
a.option-action(ng-click='list.help=!list.help', tooltip=env.t('clickForHelp'))
|
||||
span.glyphicon.glyphicon-question-sign(style={'zoom':1.5,'vertical-align':'-webkit-baseline-middle'})
|
||||
25
website/views/shared/tasks/task_view/help.jade
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
div(ng-if='list.help', ng-switch='::list.type')
|
||||
ul(ng-switch-when='habit')
|
||||
li!=env.t('habitHelp1', {plusIcon:"<span class='glyphicon glyphicon-plus'></span>"})
|
||||
li!=env.t('habitHelp2', {minusIcon:"<span class='glyphicon glyphicon-minus'></span>"})
|
||||
li!=env.t('habitHelp3')
|
||||
li!=env.t('newbieGuild', {linkStart:"<a href='https://habitrpg.com/#/options/groups/guilds/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>", linkEnd: "</a>"})
|
||||
ul(ng-switch-when='daily')
|
||||
li!=env.t('dailyHelp1', {emphasisStart:"<strong>", emphasisEnd:"</strong>", pencilIcon:"<span class='glyphicon glyphicon-pencil'></span>"})
|
||||
li=env.t('dailyHelp2')
|
||||
li!=env.t('dailyHelp3', {emphasisStart:"<strong>", emphasisEnd:"</strong>"})
|
||||
li!=env.t('dailyHelp4', {linkStart:"<a href='/#/options/settings/settings' target='_blank'>", linkEnd:"</a>"})
|
||||
li!=env.t('dailyHelp5')
|
||||
li!=env.t('newbieGuild', {linkStart:"<a href='https://habitrpg.com/#/options/groups/guilds/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>", linkEnd: "</a>"})
|
||||
ul(ng-switch-when='todo')
|
||||
li=env.t('toDoHelp1')
|
||||
li=env.t('toDoHelp2')
|
||||
li=env.t('toDoHelp3')
|
||||
li!=env.t('toDoHelp4')
|
||||
li!=env.t('newbieGuild', {linkStart:"<a href='https://habitrpg.com/#/options/groups/guilds/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>", linkEnd: "</a>"})
|
||||
ul(ng-switch-when='reward')
|
||||
li!=env.t('rewardHelp1', {linkStart:"<a href='/#/options/inventory/equipment' target='_blank'>", linkEnd: "</a>"})
|
||||
li!=env.t('rewardHelp2', {linkStart:"<a href='/#/options/profile/stats' target='_blank'>", linkEnd: "</a>"})
|
||||
li=env.t('rewardHelp3')
|
||||
li!=env.t('rewardHelp4')
|
||||
li!=env.t('newbieGuild', {linkStart:"<a href='https://habitrpg.com/#/options/groups/guilds/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>", linkEnd: "</a>"})
|
||||
35
website/views/shared/tasks/task_view/index.jade
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// left-hand side checkbox
|
||||
.task-controls.task-primary(ng-if='!task._editing')
|
||||
|
||||
// Habits
|
||||
.task-actions(ng-if='::task.type=="habit"')
|
||||
// score() is overridden in challengesCtrl to do nothing
|
||||
a(ng-if='task.up', ng-click='applyingAction || score(task,"up")')
|
||||
span.glyphicon.glyphicon-plus
|
||||
a(ng-if='task.down', ng-click='applyingAction || score(task,"down")')
|
||||
span.glyphicon.glyphicon-minus
|
||||
|
||||
// Rewards
|
||||
span(ng-if='::task.type=="reward"')
|
||||
a.money.btn-buy(ng-class='{highValue: task.value >= 1000}', ng-click='score(task, "down")')
|
||||
span.shop_gold
|
||||
span.reward-cost {{task.value}}
|
||||
|
||||
// Daily & Todos
|
||||
span.task-checker.action-yesno(ng-if='::task.type=="daily" || task.type=="todo"')
|
||||
input.visuallyhidden.focusable(id='box-{{::obj._id}}_{{::task.id}}', type='checkbox',
|
||||
ng-model='task.completed', ng-if='$state.includes("tasks")',
|
||||
ng-change='task.type=="todo" && pushTask(task,$index,"bottom"); changeCheck(task)')
|
||||
input.visuallyhidden.focusable(id='box-{{::obj._id}}_{{::task.id}}', type='checkbox',
|
||||
ng-if='!$state.includes("tasks")')
|
||||
label(for='box-{{::obj._id}}_{{::task.id}}')
|
||||
|
||||
// main content
|
||||
.task-text(ng-dblclick='task._editing ? saveTask(task) : editTask(task)')
|
||||
markdown(text='task.text',target='_blank')
|
||||
|
||||
div(ng-if='task.checklist && !$state.includes("options.social.challenges") && !task.collapseChecklist && !task._editing')
|
||||
fieldset.option-group.task-checklist
|
||||
label.checkbox(ng-repeat='item in task.checklist')
|
||||
input(type='checkbox', ng-model='item.completed', ng-change='saveTask(task,true)')
|
||||
markdown(text='item.text', target='_blank')
|
||||