mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-26 06:57:58 +01:00
Merge pull request #41 from Poniverse/feature/fixed-dates
Get dates to display properly in Pony.fm
This commit is contained in:
commit
f30f17e80a
7 changed files with 8 additions and 230 deletions
|
@ -166,7 +166,7 @@ class Album extends Model
|
||||||
'track_count' => (int)$album->track_count,
|
'track_count' => (int)$album->track_count,
|
||||||
'title' => $album->title,
|
'title' => $album->title,
|
||||||
'slug' => $album->slug,
|
'slug' => $album->slug,
|
||||||
'created_at' => $album->created_at,
|
'created_at' => $album->created_at->format('c'),
|
||||||
'stats' => [
|
'stats' => [
|
||||||
'views' => (int)$album->view_count,
|
'views' => (int)$album->view_count,
|
||||||
'downloads' => (int)$album->download_count,
|
'downloads' => (int)$album->download_count,
|
||||||
|
|
|
@ -122,7 +122,7 @@ class Playlist extends Model
|
||||||
'track_count' => $playlist->track_count,
|
'track_count' => $playlist->track_count,
|
||||||
'title' => $playlist->title,
|
'title' => $playlist->title,
|
||||||
'slug' => $playlist->slug,
|
'slug' => $playlist->slug,
|
||||||
'created_at' => $playlist->created_at,
|
'created_at' => $playlist->created_at->format('c'),
|
||||||
'is_public' => (bool)$playlist->is_public,
|
'is_public' => (bool)$playlist->is_public,
|
||||||
'stats' => [
|
'stats' => [
|
||||||
'views' => (int)$playlist->view_count,
|
'views' => (int)$playlist->view_count,
|
||||||
|
|
|
@ -330,7 +330,7 @@ class Track extends Model
|
||||||
'is_explicit' => (bool)$track->is_explicit,
|
'is_explicit' => (bool)$track->is_explicit,
|
||||||
'is_downloadable' => (bool)$track->is_downloadable,
|
'is_downloadable' => (bool)$track->is_downloadable,
|
||||||
'is_published' => (bool)$track->isPublished(),
|
'is_published' => (bool)$track->isPublished(),
|
||||||
'published_at' => $track->published_at,
|
'published_at' => $track->published_at->format('c'),
|
||||||
'duration' => $track->duration,
|
'duration' => $track->duration,
|
||||||
'genre' => $track->genre != null
|
'genre' => $track->genre != null
|
||||||
?
|
?
|
||||||
|
@ -391,8 +391,8 @@ class Track extends Model
|
||||||
'is_explicit' => $track->is_explicit,
|
'is_explicit' => $track->is_explicit,
|
||||||
'is_downloadable' => $track->is_downloadable,
|
'is_downloadable' => $track->is_downloadable,
|
||||||
'is_published' => $track->isPublished(),
|
'is_published' => $track->isPublished(),
|
||||||
'created_at' => $track->created_at,
|
'created_at' => $track->created_at->format('c'),
|
||||||
'published_at' => $track->published_at,
|
'published_at' => $track->published_at->format('c'),
|
||||||
'duration' => $track->duration,
|
'duration' => $track->duration,
|
||||||
'genre_id' => $track->genre_id,
|
'genre_id' => $track->genre_id,
|
||||||
'track_type_id' => $track->track_type_id,
|
'track_type_id' => $track->track_type_id,
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="stats">
|
<ul class="stats">
|
||||||
<li>Published: <strong bo-text="album.created_at | pfmdate:'medium'"></strong></li>
|
<li>Published: <strong bo-text="album.created_at | date:'medium'"></strong></li>
|
||||||
<li>Views: <strong bo-text="album.stats.views"></strong></li>
|
<li>Views: <strong bo-text="album.stats.views"></strong></li>
|
||||||
<li>Downloads: <strong bo-text="album.stats.downloads"></strong></li>
|
<li>Downloads: <strong bo-text="album.stats.downloads"></strong></li>
|
||||||
<li>Favourites: <strong bo-text="album.stats.favourites"></strong></li>
|
<li>Favourites: <strong bo-text="album.stats.favourites"></strong></li>
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="stats">
|
<ul class="stats">
|
||||||
<li>Created: <strong bo-text="playlist.created_at | pfmdate:'medium'"></strong></li>
|
<li>Created: <strong bo-text="playlist.created_at | date:'medium'"></strong></li>
|
||||||
<li>Views: <strong bo-text="playlist.stats.views"></strong></li>
|
<li>Views: <strong bo-text="playlist.stats.views"></strong></li>
|
||||||
<li>Downloads: <strong bo-text="playlist.stats.downloads"></strong></li>
|
<li>Downloads: <strong bo-text="playlist.stats.downloads"></strong></li>
|
||||||
<li>Favourites: <strong bo-text="playlist.stats.favourites"></strong></li>
|
<li>Favourites: <strong bo-text="playlist.stats.favourites"></strong></li>
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="stats">
|
<ul class="stats">
|
||||||
<li>Published: <strong bo-text="track.published_at | pfmdate:'medium'"></strong></li>
|
<li>Published: <strong bo-text="track.published_at | date:'medium'"></strong></li>
|
||||||
<li>Views: <strong bo-text="track.stats.views"></strong></li>
|
<li>Views: <strong bo-text="track.stats.views"></strong></li>
|
||||||
<li>Plays: <strong bo-text="track.stats.plays"></strong></li>
|
<li>Plays: <strong bo-text="track.stats.plays"></strong></li>
|
||||||
<li>Downloads: <strong bo-text="track.stats.downloads"></strong></li>
|
<li>Downloads: <strong bo-text="track.stats.downloads"></strong></li>
|
||||||
|
|
|
@ -1,222 +0,0 @@
|
||||||
/*
|
|
||||||
If you're wondering, this is indeed a copy/paste of angular's date filter with all of its internal dependencies.
|
|
||||||
Why, you ask? Well, I needed to add lines 190 and 191, and didn't want to edit the source of angular itself.
|
|
||||||
Now this filter supports dates returned directly from Carbon.
|
|
||||||
*/
|
|
||||||
|
|
||||||
angular.module('ponyfm').filter('pfmdate', [
|
|
||||||
'$locale',
|
|
||||||
function($locale) {
|
|
||||||
function isString(value){return typeof value == 'string';}
|
|
||||||
function isNumber(value){return typeof value == 'number';}
|
|
||||||
|
|
||||||
function isDate(value){
|
|
||||||
if (!value)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return Object.prototype.toString.apply(value) == '[object Date]';
|
|
||||||
}
|
|
||||||
|
|
||||||
function padNumber(num, digits, trim) {
|
|
||||||
var neg = '';
|
|
||||||
if (num < 0) {
|
|
||||||
neg = '-';
|
|
||||||
num = -num;
|
|
||||||
}
|
|
||||||
num = '' + num;
|
|
||||||
while(num.length < digits) num = '0' + num;
|
|
||||||
if (trim)
|
|
||||||
num = num.substr(num.length - digits);
|
|
||||||
return neg + num;
|
|
||||||
}
|
|
||||||
|
|
||||||
function int(str) {
|
|
||||||
return parseInt(str, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
function concat(array1, array2, index) {
|
|
||||||
return array1.concat([].slice.call(array2, index));
|
|
||||||
}
|
|
||||||
|
|
||||||
function isArrayLike(obj) {
|
|
||||||
if (!obj || (typeof obj.length !== 'number')) return false;
|
|
||||||
|
|
||||||
// We have on object which has length property. Should we treat it as array?
|
|
||||||
if (typeof obj.hasOwnProperty != 'function' &&
|
|
||||||
typeof obj.constructor != 'function') {
|
|
||||||
// This is here for IE8: it is a bogus object treat it as array;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return obj instanceof JQLite || // JQLite
|
|
||||||
(jQuery && obj instanceof jQuery) || // jQuery
|
|
||||||
toString.call(obj) !== '[object Object]' || // some browser native object
|
|
||||||
typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isFunction(value){return typeof value == 'function';}
|
|
||||||
|
|
||||||
function forEach(obj, iterator, context) {
|
|
||||||
var key;
|
|
||||||
if (obj) {
|
|
||||||
if (isFunction(obj)){
|
|
||||||
for (key in obj) {
|
|
||||||
if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) {
|
|
||||||
iterator.call(context, obj[key], key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (obj.forEach && obj.forEach !== forEach) {
|
|
||||||
obj.forEach(iterator, context);
|
|
||||||
} else if (isArrayLike(obj)) {
|
|
||||||
for (key = 0; key < obj.length; key++)
|
|
||||||
iterator.call(context, obj[key], key);
|
|
||||||
} else {
|
|
||||||
for (key in obj) {
|
|
||||||
if (obj.hasOwnProperty(key)) {
|
|
||||||
iterator.call(context, obj[key], key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
var uppercase = function(string){return isString(string) ? string.toUpperCase() : string;};
|
|
||||||
|
|
||||||
var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,
|
|
||||||
NUMBER_STRING = /^\d+$/;
|
|
||||||
|
|
||||||
var DATE_FORMATS = {
|
|
||||||
yyyy: dateGetter('FullYear', 4),
|
|
||||||
yy: dateGetter('FullYear', 2, 0, true),
|
|
||||||
y: dateGetter('FullYear', 1),
|
|
||||||
MMMM: dateStrGetter('Month'),
|
|
||||||
MMM: dateStrGetter('Month', true),
|
|
||||||
MM: dateGetter('Month', 2, 1),
|
|
||||||
M: dateGetter('Month', 1, 1),
|
|
||||||
dd: dateGetter('Date', 2),
|
|
||||||
d: dateGetter('Date', 1),
|
|
||||||
HH: dateGetter('Hours', 2),
|
|
||||||
H: dateGetter('Hours', 1),
|
|
||||||
hh: dateGetter('Hours', 2, -12),
|
|
||||||
h: dateGetter('Hours', 1, -12),
|
|
||||||
mm: dateGetter('Minutes', 2),
|
|
||||||
m: dateGetter('Minutes', 1),
|
|
||||||
ss: dateGetter('Seconds', 2),
|
|
||||||
s: dateGetter('Seconds', 1),
|
|
||||||
// while ISO 8601 requires fractions to be prefixed with `.` or `,`
|
|
||||||
// we can be just safely rely on using `sss` since we currently don't support single or two digit fractions
|
|
||||||
sss: dateGetter('Milliseconds', 3),
|
|
||||||
EEEE: dateStrGetter('Day'),
|
|
||||||
EEE: dateStrGetter('Day', true),
|
|
||||||
a: ampmGetter,
|
|
||||||
Z: timeZoneGetter
|
|
||||||
};
|
|
||||||
|
|
||||||
function dateGetter(name, size, offset, trim) {
|
|
||||||
offset = offset || 0;
|
|
||||||
return function(date) {
|
|
||||||
var value = date['get' + name]();
|
|
||||||
if (offset > 0 || value > -offset)
|
|
||||||
value += offset;
|
|
||||||
if (value === 0 && offset == -12 ) value = 12;
|
|
||||||
return padNumber(value, size, trim);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function dateStrGetter(name, shortForm) {
|
|
||||||
return function(date, formats) {
|
|
||||||
var value = date['get' + name]();
|
|
||||||
var get = uppercase(shortForm ? ('SHORT' + name) : name);
|
|
||||||
|
|
||||||
return formats[get][value];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function timeZoneGetter(date) {
|
|
||||||
var zone = -1 * date.getTimezoneOffset();
|
|
||||||
var paddedZone = (zone >= 0) ? "+" : "";
|
|
||||||
|
|
||||||
paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
|
|
||||||
padNumber(Math.abs(zone % 60), 2);
|
|
||||||
|
|
||||||
return paddedZone;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ampmGetter(date, formats) {
|
|
||||||
return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
|
|
||||||
function jsonStringToDate(string) {
|
|
||||||
var match;
|
|
||||||
if (match = string.match(R_ISO8601_STR)) {
|
|
||||||
var date = new Date(0),
|
|
||||||
tzHour = 0,
|
|
||||||
tzMin = 0,
|
|
||||||
dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,
|
|
||||||
timeSetter = match[8] ? date.setUTCHours : date.setHours;
|
|
||||||
|
|
||||||
if (match[9]) {
|
|
||||||
tzHour = int(match[9] + match[10]);
|
|
||||||
tzMin = int(match[9] + match[11]);
|
|
||||||
}
|
|
||||||
dateSetter.call(date, int(match[1]), int(match[2]) - 1, int(match[3]));
|
|
||||||
var h = int(match[4]||0) - tzHour;
|
|
||||||
var m = int(match[5]||0) - tzMin;
|
|
||||||
var s = int(match[6]||0);
|
|
||||||
var ms = Math.round(parseFloat('0.' + (match[7]||0)) * 1000);
|
|
||||||
timeSetter.call(date, h, m, s, ms);
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return function(date, format) {
|
|
||||||
var text = '',
|
|
||||||
parts = [],
|
|
||||||
fn, match;
|
|
||||||
|
|
||||||
if (typeof(date) == 'object' && date.date) {
|
|
||||||
date = date.date;
|
|
||||||
}
|
|
||||||
|
|
||||||
format = format || 'mediumDate';
|
|
||||||
format = $locale.DATETIME_FORMATS[format] || format;
|
|
||||||
if (isString(date)) {
|
|
||||||
if (NUMBER_STRING.test(date)) {
|
|
||||||
date = int(date);
|
|
||||||
} else {
|
|
||||||
date = jsonStringToDate(date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNumber(date)) {
|
|
||||||
date = new Date(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDate(date)) {
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(format) {
|
|
||||||
match = DATE_FORMATS_SPLIT.exec(format);
|
|
||||||
if (match) {
|
|
||||||
parts = concat(parts, match, 1);
|
|
||||||
format = parts.pop();
|
|
||||||
} else {
|
|
||||||
parts.push(format);
|
|
||||||
format = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forEach(parts, function(value){
|
|
||||||
fn = DATE_FORMATS[value];
|
|
||||||
text += fn ? fn(date, $locale.DATETIME_FORMATS)
|
|
||||||
: value.replace(/(^'|'$)/g, '').replace(/''/g, "'");
|
|
||||||
});
|
|
||||||
|
|
||||||
return text;
|
|
||||||
};
|
|
||||||
}]);
|
|
Loading…
Reference in a new issue