Last active
December 20, 2015 00:09
-
-
Save marshall007/6039852 to your computer and use it in GitHub Desktop.
AngularJS "Time Ago" filter.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
timeAgo = angular.module 'app' | |
# Filter: time | |
# Date.parse() is inconsistent across browsers | |
# this is a shim for parsing ISO-8601 date strings | |
timeAgo.filter 'time', -> | |
(time) -> | |
return if not time | |
return time if angular.isDate time | |
return new Date time if angular.isNumber time | |
time = time.replace /\.\d+/, '' | |
time = time.replace(/-/, '/').replace /-/, '/' | |
time = time.replace(/T/, ' ').replace /Z/, ' UTC' | |
time = time.replace /([\+\-]\d\d)\:?(\d\d)/, ' $1$2' | |
time = new Date time * 1000 or time | |
# Filter: timeAgo | |
# Allows you to override any of the default templates | |
timeAgo.constant 'timeAgoTemplates', {} | |
timeAgo.filter 'timeAgo', [ | |
'timeFilter', 'timeAgoTemplates' | |
(normalize, config) -> | |
templates = | |
default: 'Never' | |
prefix: '' | |
suffix: 'ago' | |
seconds: 'less than a minute' | |
minute: 'a minute' | |
minutes: '%d minutes' | |
hour: 'an hour' | |
hours: '%d hours' | |
day: 'a day' | |
days: '%d days' | |
month: 'a month' | |
months: '%d months' | |
year: 'a year' | |
years: '%d years' | |
angular.extend templates, config | |
template = (t, n) -> | |
templates[t]?.replace /%d/i, Math.abs Math.round n | |
build = -> # (prefix, value, suffix) -> | |
args = Array.prototype.slice.call arguments, 0 | |
return args.map (a) -> | |
a.trim() | |
.join(' ').trim() | |
(time, none, prefix) -> | |
none = none or templates.default | |
prefix = prefix or templates.prefix | |
time = normalize time | |
return none if not time | |
now = new Date | |
seconds = ((now.getTime() - time) * .001) >> 0 | |
minutes = seconds / 60 | |
hours = minutes / 60 | |
days = hours / 24 | |
years = days / 365 | |
return build prefix, ( | |
seconds < 45 and template('seconds', seconds) or | |
seconds < 90 and template('minute', 1) or | |
minutes < 45 and template('minutes', minutes) or | |
minutes < 90 and template('hour', 1) or | |
hours < 24 and template('hours', hours) or | |
hours < 42 and template('day', 1) or | |
days < 30 and template('days', days) or | |
days < 45 and template('month', 1) or | |
days < 365 and template('months', days / 30) or | |
years < 1.5 and template('year', 1) or | |
template 'years', years | |
), templates.suffix | |
] | |
# Directive: <time-ago> | |
timeAgo.directive 'timeAgo', [ | |
'$interval', 'timeFilter', | |
($interval, normalize) -> | |
restrict: 'E' | |
replace: true | |
scope: | |
default: '@' | |
prefix: '@' | |
time: '=' | |
template: """ | |
<time datetime="{{ time }}" | |
title="{{ time | date:'short' }}"> | |
{{ time | timeAgo:default:prefix }} | |
</time> | |
""" | |
link: (scope) -> | |
clear = null | |
scope.$watch 'time', (value) -> | |
$interval.cancel clear if clear | |
hours = (Date.now() - normalize value) / 3600000 | |
# update every 30 seconds if less than an hour has passed | |
if hours < 1 | |
clear = $interval angular.noop, 30000 | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
awesome, modified it a bit to create an auto updating directive