Update dotfiles
3
.bowerrc
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"directory": "app/bower_components"
|
||||
"directory": "bower_components",
|
||||
"analytics": false
|
||||
}
|
||||
|
|
|
@ -6,16 +6,29 @@ root = true
|
|||
|
||||
|
||||
[*]
|
||||
|
||||
# Change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
# We recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
[*.js]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.hbs]
|
||||
insert_final_newline = false
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.css]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.html]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{diff,md}]
|
||||
trim_trailing_whitespace = false
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
/**
|
||||
Ember CLI sends analytics information by default. The data is completely
|
||||
anonymous, but there are times when you might want to disable this behavior.
|
||||
|
||||
Setting `disableAnalytics` to true will prevent any data from being sent.
|
||||
*/
|
||||
"disableAnalytics": false
|
||||
}
|
|
@ -1,8 +1,17 @@
|
|||
node_modules
|
||||
temp
|
||||
dist
|
||||
.sass-cache
|
||||
.tmp
|
||||
app/bower_components
|
||||
.DS_Store
|
||||
.grunt
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/bower_components
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage/*
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
testem.log
|
||||
|
|
58
.jshintrc
|
@ -1,28 +1,34 @@
|
|||
{
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"esnext": true,
|
||||
"bitwise": false,
|
||||
"curly": false,
|
||||
"eqeqeq": true,
|
||||
"eqnull": true,
|
||||
"immed": true,
|
||||
"latedef": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"undef": true,
|
||||
"strict": false,
|
||||
"trailing": false,
|
||||
"smarttabs": true,
|
||||
"globals": {
|
||||
"HighFidelity": true,
|
||||
"$": true,
|
||||
"jQuery": true,
|
||||
"Ember": true,
|
||||
"Handlebars": true,
|
||||
"DS": true,
|
||||
"Promise": true,
|
||||
"I18n": true,
|
||||
"localforage": true
|
||||
}
|
||||
"predef": [
|
||||
"document",
|
||||
"window",
|
||||
"-Promise",
|
||||
"$",
|
||||
"EmberHifi"
|
||||
],
|
||||
"browser": true,
|
||||
"boss": true,
|
||||
"curly": true,
|
||||
"debug": false,
|
||||
"devel": true,
|
||||
"eqeqeq": true,
|
||||
"evil": true,
|
||||
"forin": false,
|
||||
"immed": false,
|
||||
"laxbreak": false,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": false,
|
||||
"nonew": false,
|
||||
"nomen": false,
|
||||
"onevar": false,
|
||||
"plusplus": false,
|
||||
"regexp": false,
|
||||
"undef": true,
|
||||
"sub": true,
|
||||
"strict": false,
|
||||
"white": false,
|
||||
"eqnull": true,
|
||||
"esnext": true,
|
||||
"unused": true
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<!-- TODO: Localize title -->
|
||||
<title>Podcasts</title>
|
||||
<meta name="description" content="Podcasts in your browser and your phone.">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
|
||||
<!-- iOS-specific meta information; for homescreen web app capabilities -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<!-- iPhone -->
|
||||
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="apple-touch-icon-57x57-precomposed.png">
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 320px)" href="img/default.png">
|
||||
<!-- Retina iPhone -->
|
||||
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="apple-touch-icon-114x114-precomposed.png">
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 320px) and (-webkit-device-pixel-ratio: 2)" href="img/default@2x.png">
|
||||
|
||||
<!-- Enable Cleartype for MS Browsers -->
|
||||
<meta http-equiv="cleartype" content="on">
|
||||
|
||||
<!-- Responsive and mobile friendly stuff -->
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="MobileOptimized" content="320">
|
||||
|
||||
<!-- build:css(app) styles/vendor.css -->
|
||||
<link rel="stylesheet" href="bower_components/normalize.css/normalize.css">
|
||||
<link rel="stylesheet" href="bower_components/brick/dist/brick.css">
|
||||
<link rel="stylesheet" href="bower_components/fontawesome/css/font-awesome.css">
|
||||
<!-- endbuild -->
|
||||
|
||||
<!-- build:css(.tmp) styles/app.css -->
|
||||
<link rel="stylesheet" href="styles/compiled-stylus.css">
|
||||
<!-- endbuild -->
|
||||
</head>
|
||||
<body>
|
||||
<!-- build:js(app) scripts/vendor.js -->
|
||||
<script src="bower_components/jquery/jquery.js"></script>
|
||||
<script src="bower_components/handlebars/handlebars.runtime.js"></script>
|
||||
<script src="bower_components/ember/ember.prod.js"></script>
|
||||
<script src="bower_components/ember-data/ember-data.prod.js"></script>
|
||||
<script src="bower_components/brick/dist/brick.js"></script>
|
||||
<script src="bower_components/localforage/dist/localforage.js"></script>
|
||||
<script src="bower_components/i18n-js/app/assets/javascripts/i18n.js"></script>
|
||||
<script src="bower_components/ember-indexeddb-adapter/dist/ember_indexeddb_adapter.js"></script>
|
||||
<!-- endbuild -->
|
||||
|
||||
<!-- build:js(.tmp) scripts/app.js -->
|
||||
<script src="scripts/compiled-templates.js"></script>
|
||||
<script src="scripts/combined-scripts.js"></script>
|
||||
<!-- endbuild -->
|
||||
</body>
|
||||
</html>
|
||||
<!-- I can still hear you saying you would never break the chain -->
|
|
@ -0,0 +1,627 @@
|
|||
Ember.TEMPLATES["application"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
|
||||
this.compilerInfo = [4,'>= 1.0.0'];
|
||||
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
var buffer = '', stack1, stack2, hashTypes, hashContexts, options, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, self=this;
|
||||
|
||||
function program1(depth0,data) {
|
||||
|
||||
var stack1, hashTypes, hashContexts, options;
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "tabs.myPodcasts", options) : helperMissing.call(depth0, "t", "tabs.myPodcasts", options))));
|
||||
}
|
||||
|
||||
function program3(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, stack2, hashTypes, hashContexts, options;
|
||||
data.buffer.push("\n ");
|
||||
data.buffer.push("\n <x-tabbar-tab>\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},inverse:self.noop,fn:self.program(4, program4, data),contexts:[depth0],types:["STRING"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
stack2 = ((stack1 = helpers['link-to'] || depth0['link-to']),stack1 ? stack1.call(depth0, "search", options) : helperMissing.call(depth0, "link-to", "search", options));
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n </x-tabbar-tab>\n ");
|
||||
return buffer;
|
||||
}
|
||||
function program4(depth0,data) {
|
||||
|
||||
var stack1, hashTypes, hashContexts, options;
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "tabs.search", options) : helperMissing.call(depth0, "t", "tabs.search", options))));
|
||||
}
|
||||
|
||||
data.buffer.push("<x-layout>\n <header>\n <x-appbar>\n <h1>");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "app.title", options) : helperMissing.call(depth0, "t", "app.title", options))));
|
||||
data.buffer.push("</h1>\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers.outlet || depth0.outlet),stack1 ? stack1.call(depth0, "headerAction", options) : helperMissing.call(depth0, "outlet", "headerAction", options))));
|
||||
data.buffer.push("\n </x-appbar>\n </header>\n <section>\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "outlet", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("\n </section>\n <footer>\n ");
|
||||
data.buffer.push("\n <audio id=\"audio-player\" preload=\"auto\" mozaudiochannel=\"content\"></audio>\n\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["STRING"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers.render || depth0.render),stack1 ? stack1.call(depth0, "player", options) : helperMissing.call(depth0, "render", "player", options))));
|
||||
data.buffer.push("\n\n <x-tabbar>\n <x-tabbar-tab selected=\"true\">\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},inverse:self.noop,fn:self.program(1, program1, data),contexts:[depth0],types:["STRING"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
stack2 = ((stack1 = helpers['link-to'] || depth0['link-to']),stack1 ? stack1.call(depth0, "podcasts", options) : helperMissing.call(depth0, "link-to", "podcasts", options));
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n </x-tabbar-tab>\n\n ");
|
||||
data.buffer.push("\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
stack2 = helpers['if'].call(depth0, "isPackaged", {hash:{},inverse:self.noop,fn:self.program(3, program3, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n </x-tabbar>\n </footer>\n</x-layout>\n");
|
||||
return buffer;
|
||||
|
||||
});
|
||||
|
||||
Ember.TEMPLATES["episodes"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
|
||||
this.compilerInfo = [4,'>= 1.0.0'];
|
||||
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
var buffer = '', stack1, hashContexts, hashTypes, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, self=this;
|
||||
|
||||
function program1(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, stack2, hashTypes, hashContexts, options;
|
||||
data.buffer.push("\n <div ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "setEpisode", "", {hash:{},contexts:[depth0,depth0],types:["ID","ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push(" ");
|
||||
hashContexts = {'class': depth0};
|
||||
hashTypes = {'class': "STRING"};
|
||||
options = {hash:{
|
||||
'class': (":episode isNew")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push(">\n <div class=\"name\">\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
stack2 = helpers['if'].call(depth0, "isNew", {hash:{},inverse:self.noop,fn:self.program(2, program2, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "name", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("\n </div>\n\n ");
|
||||
data.buffer.push("\n </div>\n ");
|
||||
return buffer;
|
||||
}
|
||||
function program2(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, hashTypes, hashContexts, options;
|
||||
data.buffer.push("\n <strong>");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "episode.new", options) : helperMissing.call(depth0, "t", "episode.new", options))));
|
||||
data.buffer.push("</strong>\n ");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function program4(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, hashTypes, hashContexts, options;
|
||||
data.buffer.push("\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers.render || depth0.render),stack1 ? stack1.call(depth0, "spinner", options) : helperMissing.call(depth0, "render", "spinner", options))));
|
||||
data.buffer.push("\n ");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
data.buffer.push("<div class=\"episodes\">\n ");
|
||||
hashContexts = {'content': depth0};
|
||||
hashTypes = {'content': "ID"};
|
||||
stack1 = helpers.each.call(depth0, {hash:{
|
||||
'content': ("controller")
|
||||
},inverse:self.program(4, program4, data),fn:self.program(1, program1, data),contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
|
||||
data.buffer.push("\n</div>\n");
|
||||
return buffer;
|
||||
|
||||
});
|
||||
|
||||
Ember.TEMPLATES["header-actions/podcast"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
|
||||
this.compilerInfo = [4,'>= 1.0.0'];
|
||||
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
var buffer = '', hashTypes, hashContexts, escapeExpression=this.escapeExpression;
|
||||
|
||||
|
||||
data.buffer.push("<h1>");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "title", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("</h1>\n<button class=\"update\" ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "update", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("><i class=\"fa fa-refresh\"></i></button>\n");
|
||||
return buffer;
|
||||
|
||||
});
|
||||
|
||||
Ember.TEMPLATES["header-actions/podcasts"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
|
||||
this.compilerInfo = [4,'>= 1.0.0'];
|
||||
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
var buffer = '', stack1, stack2, hashTypes, hashContexts, options, self=this, helperMissing=helpers.helperMissing;
|
||||
|
||||
function program1(depth0,data) {
|
||||
|
||||
|
||||
data.buffer.push("<i class=\"fa fa-plus\"></i>");
|
||||
}
|
||||
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},inverse:self.noop,fn:self.program(1, program1, data),contexts:[depth0],types:["STRING"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
stack2 = ((stack1 = helpers['link-to'] || depth0['link-to']),stack1 ? stack1.call(depth0, "podcast.new", options) : helperMissing.call(depth0, "link-to", "podcast.new", options));
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n");
|
||||
return buffer;
|
||||
|
||||
});
|
||||
|
||||
Ember.TEMPLATES["player"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
|
||||
this.compilerInfo = [4,'>= 1.0.0'];
|
||||
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
var buffer = '', stack1, stack2, hashContexts, hashTypes, options, escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
|
||||
|
||||
function program1(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, stack2, hashContexts, hashTypes, options;
|
||||
data.buffer.push("\n <div id=\"time-info\">\n <progress id=\"audio-progress\" ");
|
||||
hashContexts = {'max': depth0};
|
||||
hashTypes = {'max': "ID"};
|
||||
options = {hash:{
|
||||
'max': ("progressBar.max")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push("\n ");
|
||||
hashContexts = {'value': depth0};
|
||||
hashTypes = {'value': "ID"};
|
||||
options = {hash:{
|
||||
'value': ("progressBar.value")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push(">\n </progress>\n \n <span id=\"time-elapsed\">");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "timeElapsed", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("</span>\n <span id=\"time-remaining\">");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "timeTotal", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("</span>\n </div>\n \n <div class=\"episode-name\">");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "name", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("</div>\n \n <div class=\"player-controls\">\n <a ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "rewind", "model", {hash:{},contexts:[depth0,depth0],types:["ID","ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push(" class=\"backward\">\n <i class=\"fa fa-backward\"></i>\n </a>\n \n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
stack2 = helpers['if'].call(depth0, "isPlaying", {hash:{},inverse:self.program(4, program4, data),fn:self.program(2, program2, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n \n <a ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "forward", "model", {hash:{},contexts:[depth0,depth0],types:["ID","ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push(" class=\"forward\">\n <i class=\"fa fa-forward\"></i>\n </a>\n </div>\n ");
|
||||
return buffer;
|
||||
}
|
||||
function program2(depth0,data) {
|
||||
|
||||
var buffer = '', hashTypes, hashContexts;
|
||||
data.buffer.push("\n <a ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "pause", "model", {hash:{},contexts:[depth0,depth0],types:["ID","ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push(" class=\"play-pause\">\n <i class=\"fa fa-pause\"></i>\n </a>\n ");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function program4(depth0,data) {
|
||||
|
||||
var buffer = '', hashTypes, hashContexts;
|
||||
data.buffer.push("\n <a ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "play", "model", {hash:{},contexts:[depth0,depth0],types:["ID","ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push(" class=\"play-pause\">\n <i class=\"fa fa-play\"></i>\n </a>\n ");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
data.buffer.push("<div id=\"player\" ");
|
||||
hashContexts = {'class': depth0};
|
||||
hashTypes = {'class': "STRING"};
|
||||
options = {hash:{
|
||||
'class': ("isPopulated")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push(">\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
stack2 = helpers['if'].call(depth0, "audio", {hash:{},inverse:self.noop,fn:self.program(1, program1, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n</div>\n");
|
||||
return buffer;
|
||||
|
||||
});
|
||||
|
||||
Ember.TEMPLATES["podcast"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
|
||||
this.compilerInfo = [4,'>= 1.0.0'];
|
||||
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
var buffer = '', stack1, hashContexts, hashTypes, options, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
|
||||
|
||||
|
||||
data.buffer.push("<div class=\"podcast\">\n <img class=\"cover-image\" ");
|
||||
hashContexts = {'src': depth0};
|
||||
hashTypes = {'src': "ID"};
|
||||
options = {hash:{
|
||||
'src': ("coverImageURL")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push("\n ");
|
||||
hashContexts = {'alt': depth0};
|
||||
hashTypes = {'alt': "ID"};
|
||||
options = {hash:{
|
||||
'alt': ("title")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push(">\n\n <p>");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "description", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("</p>\n\n <button ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "delete", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push(">Unsubscribe</button>\n ");
|
||||
data.buffer.push("\n</div>\n\n<hr/>\n\n");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0,depth0],types:["ID","ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers.render || depth0.render),stack1 ? stack1.call(depth0, "episodes", "episodes", options) : helperMissing.call(depth0, "render", "episodes", "episodes", options))));
|
||||
data.buffer.push("\n\n");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "outlet", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("\n");
|
||||
return buffer;
|
||||
|
||||
});
|
||||
|
||||
Ember.TEMPLATES["podcast/new"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
|
||||
this.compilerInfo = [4,'>= 1.0.0'];
|
||||
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
var buffer = '', stack1, stack2, hashTypes, hashContexts, options, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, self=this;
|
||||
|
||||
function program1(depth0,data) {
|
||||
|
||||
|
||||
data.buffer.push("\n <div class=\"error\">\n <p>Encountered an error while adding Podcast.<p>\n <p>Is the Podcast URL valid?</p>\n </div>\n");
|
||||
}
|
||||
|
||||
function program3(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, hashTypes, hashContexts, options;
|
||||
data.buffer.push("\n <div class=\"full-screen\">\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers.render || depth0.render),stack1 ? stack1.call(depth0, "spinner", options) : helperMissing.call(depth0, "render", "spinner", options))));
|
||||
data.buffer.push("\n </div>\n");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
data.buffer.push("<h2>");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "podcast.addRSSFeed", options) : helperMissing.call(depth0, "t", "podcast.addRSSFeed", options))));
|
||||
data.buffer.push("</h2>\n\n");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
stack2 = helpers['if'].call(depth0, "isInErrorState", {hash:{},inverse:self.noop,fn:self.program(1, program1, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n\n");
|
||||
hashContexts = {'type': depth0,'value': depth0,'placeholder': depth0};
|
||||
hashTypes = {'type': "STRING",'value': "ID",'placeholder': "STRING"};
|
||||
options = {hash:{
|
||||
'type': ("url"),
|
||||
'value': ("rssURL"),
|
||||
'placeholder': ("Podcast URL")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers.input || depth0.input),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "input", options))));
|
||||
data.buffer.push("\n<button ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "create", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push(">");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "podcast.add", options) : helperMissing.call(depth0, "t", "podcast.add", options))));
|
||||
data.buffer.push("</button>\n\n<h2>");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "podcast.newToPodcasts", options) : helperMissing.call(depth0, "t", "podcast.newToPodcasts", options))));
|
||||
data.buffer.push("</h2>\n<h3>");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "podcast.recommendations", options) : helperMissing.call(depth0, "t", "podcast.recommendations", options))));
|
||||
data.buffer.push("</h3>\n\n<h4>The Cracked Podcast</h4>\n<img alt=\"The Cracked Podcast\" class=\"cover cover-image\"\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "create", "http://rss.earwolf.com/the-cracked-podcast", {hash:{},contexts:[depth0,depth0],types:["ID","STRING"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("\n src=\"http://cdn.earwolf.com/wp-content/uploads/2013/08/EAR_CrackedPodcast_1600x1600_Cover_Final.jpg\">\n\n<h4>Hello Internet</h4>\n<img alt=\"Hello Internet\" class=\"cover cover-image\"\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "create", "http://feeds.podtrac.com/m2lTaLRx8AWb", {hash:{},contexts:[depth0,depth0],types:["ID","STRING"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("\n src=\"http://static.squarespace.com/static/52d66949e4b0a8cec3bcdd46/t/52ebf67fe4b0f4af2a4502d8/1391195777839/1500w/Hello%20Internet.003.png\">\n\n");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
stack2 = helpers['if'].call(depth0, "isAdding", {hash:{},inverse:self.noop,fn:self.program(3, program3, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n");
|
||||
return buffer;
|
||||
|
||||
});
|
||||
|
||||
Ember.TEMPLATES["podcasts"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
|
||||
this.compilerInfo = [4,'>= 1.0.0'];
|
||||
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
var buffer = '', stack1, hashTypes, hashContexts, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, self=this;
|
||||
|
||||
function program1(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, hashContexts, hashTypes;
|
||||
data.buffer.push("\n <ul class=\"my-podcasts\">\n ");
|
||||
hashContexts = {'content': depth0,'tagName': depth0,'className': depth0};
|
||||
hashTypes = {'content': "ID",'tagName': "ID",'className': "STRING"};
|
||||
stack1 = helpers.each.call(depth0, {hash:{
|
||||
'content': ("controller"),
|
||||
'tagName': ("ul"),
|
||||
'className': ("my-podcasts")
|
||||
},inverse:self.noop,fn:self.program(2, program2, data),contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
|
||||
data.buffer.push("\n </ul>\n");
|
||||
return buffer;
|
||||
}
|
||||
function program2(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, stack2, hashContexts, hashTypes, options;
|
||||
data.buffer.push("\n <li>\n ");
|
||||
hashContexts = {'class': depth0};
|
||||
hashTypes = {'class': "STRING"};
|
||||
options = {hash:{
|
||||
'class': ("cover")
|
||||
},inverse:self.noop,fn:self.program(3, program3, data),contexts:[depth0,depth0],types:["STRING","ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
stack2 = ((stack1 = helpers['link-to'] || depth0['link-to']),stack1 ? stack1.call(depth0, "podcast", "", options) : helperMissing.call(depth0, "link-to", "podcast", "", options));
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n </li>\n ");
|
||||
return buffer;
|
||||
}
|
||||
function program3(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, hashTypes, hashContexts;
|
||||
data.buffer.push("\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
stack1 = helpers['if'].call(depth0, "coverImage", {hash:{},inverse:self.program(6, program6, data),fn:self.program(4, program4, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
|
||||
data.buffer.push("\n ");
|
||||
return buffer;
|
||||
}
|
||||
function program4(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, hashContexts, hashTypes, options;
|
||||
data.buffer.push("\n <img ");
|
||||
hashContexts = {'src': depth0};
|
||||
hashTypes = {'src': "ID"};
|
||||
options = {hash:{
|
||||
'src': ("coverImage")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push(" ");
|
||||
hashContexts = {'alt': depth0};
|
||||
hashTypes = {'alt': "ID"};
|
||||
options = {hash:{
|
||||
'alt': ("title")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push(">\n ");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function program6(depth0,data) {
|
||||
|
||||
var buffer = '', hashTypes, hashContexts;
|
||||
data.buffer.push("\n <span class=\"no-cover\">");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "title", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("</span>\n ");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function program8(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, stack2, hashTypes, hashContexts, options;
|
||||
data.buffer.push("\n <div class=\"center\">\n <h2>");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "podcast.noneFound", options) : helperMissing.call(depth0, "t", "podcast.noneFound", options))));
|
||||
data.buffer.push("</h2>\n <p>\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},inverse:self.noop,fn:self.program(9, program9, data),contexts:[depth0],types:["STRING"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
stack2 = ((stack1 = helpers['link-to'] || depth0['link-to']),stack1 ? stack1.call(depth0, "podcast.new", options) : helperMissing.call(depth0, "link-to", "podcast.new", options));
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n </p>\n </div>\n");
|
||||
return buffer;
|
||||
}
|
||||
function program9(depth0,data) {
|
||||
|
||||
var stack1, hashTypes, hashContexts, options;
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "podcast.addOne", options) : helperMissing.call(depth0, "t", "podcast.addOne", options))));
|
||||
}
|
||||
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
stack1 = helpers['if'].call(depth0, "controller", {hash:{},inverse:self.program(8, program8, data),fn:self.program(1, program1, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
|
||||
data.buffer.push("\n\n");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "outlet", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("\n");
|
||||
return buffer;
|
||||
|
||||
});
|
||||
|
||||
Ember.TEMPLATES["search"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
|
||||
this.compilerInfo = [4,'>= 1.0.0'];
|
||||
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
var buffer = '', stack1, stack2, hashTypes, hashContexts, options, escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
|
||||
|
||||
function program1(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, hashTypes, hashContexts;
|
||||
data.buffer.push("\n <div class=\"results\">\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
stack1 = helpers.each.call(depth0, "results", {hash:{},inverse:self.program(4, program4, data),fn:self.program(2, program2, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
|
||||
data.buffer.push("\n </div>\n");
|
||||
return buffer;
|
||||
}
|
||||
function program2(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, hashTypes, hashContexts, options;
|
||||
data.buffer.push("\n <div class=\"podcast\" ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "subscribe", "feedUrl", "trackName", {hash:{},contexts:[depth0,depth0,depth0],types:["ID","ID","ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push(">\n <div class=\"name\" ");
|
||||
hashContexts = {'data-collection-url': depth0};
|
||||
hashTypes = {'data-collection-url': "ID"};
|
||||
options = {hash:{
|
||||
'data-collection-url': ("feedUrl")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push(">\n <img ");
|
||||
hashContexts = {'src': depth0};
|
||||
hashTypes = {'src': "ID"};
|
||||
options = {hash:{
|
||||
'src': ("artworkUrl100")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push(" ");
|
||||
hashContexts = {'alt': depth0};
|
||||
hashTypes = {'alt': "ID"};
|
||||
options = {hash:{
|
||||
'alt': ("trackName")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push(">\n <br>\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "trackName", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push("\n </div>\n </div>\n ");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function program4(depth0,data) {
|
||||
|
||||
var buffer = '', stack1, hashTypes, hashContexts, options;
|
||||
data.buffer.push("\n <p>");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "search.noResults", options) : helperMissing.call(depth0, "t", "search.noResults", options))));
|
||||
data.buffer.push("</p>\n ");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
data.buffer.push("<h2>");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "search.searchForAPodcast", options) : helperMissing.call(depth0, "t", "search.searchForAPodcast", options))));
|
||||
data.buffer.push("</h2>\n\n");
|
||||
hashContexts = {'type': depth0,'value': depth0,'placeholder': depth0,'id': depth0};
|
||||
hashTypes = {'type': "STRING",'value': "ID",'placeholder': "ID",'id': "STRING"};
|
||||
options = {hash:{
|
||||
'type': ("search"),
|
||||
'value': ("query"),
|
||||
'placeholder': ("searchPlaceholder"),
|
||||
'id': ("search-input")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers.input || depth0.input),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "input", options))));
|
||||
data.buffer.push("\n<button ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
data.buffer.push(escapeExpression(helpers.action.call(depth0, "search", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
||||
data.buffer.push(">");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['t'] || depth0['t']),stack1 ? stack1.call(depth0, "search.find", options) : helperMissing.call(depth0, "t", "search.find", options))));
|
||||
data.buffer.push("</button>\n\n<div ");
|
||||
hashContexts = {'class': depth0};
|
||||
hashTypes = {'class': "STRING"};
|
||||
options = {hash:{
|
||||
'class': ("isSearching::hide")
|
||||
},contexts:[],types:[],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers['bind-attr'] || depth0['bind-attr']),stack1 ? stack1.call(depth0, options) : helperMissing.call(depth0, "bind-attr", options))));
|
||||
data.buffer.push(">\n ");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
options = {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data};
|
||||
data.buffer.push(escapeExpression(((stack1 = helpers.render || depth0.render),stack1 ? stack1.call(depth0, "spinner", options) : helperMissing.call(depth0, "render", "spinner", options))));
|
||||
data.buffer.push("\n</div>\n\n");
|
||||
hashTypes = {};
|
||||
hashContexts = {};
|
||||
stack2 = helpers['if'].call(depth0, "resultCount", {hash:{},inverse:self.noop,fn:self.program(1, program1, data),contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
|
||||
if(stack2 || stack2 === 0) { data.buffer.push(stack2); }
|
||||
data.buffer.push("\n");
|
||||
return buffer;
|
||||
|
||||
});
|
||||
|
||||
Ember.TEMPLATES["spinner"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
|
||||
this.compilerInfo = [4,'>= 1.0.0'];
|
||||
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
|
||||
|
||||
|
||||
|
||||
data.buffer.push("<div class=\"spinner\">\n <div class=\"rect1\"></div>\n <div class=\"rect2\"></div>\n <div class=\"rect3\"></div>\n <div class=\"rect4\"></div>\n <div class=\"rect5\"></div>\n</div>\n");
|
||||
|
||||
});
|
|
@ -0,0 +1,306 @@
|
|||
.full-screen {
|
||||
background: rgba(0,0,0,0.35);
|
||||
color: #f2f2f2;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 10000;
|
||||
}
|
||||
.full-screen .spinner {
|
||||
color: #f2f2f2;
|
||||
margin: 100px auto;
|
||||
}
|
||||
hr {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
ul,
|
||||
dl,
|
||||
ol {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
.fxos11 x-layout {
|
||||
min-height: 460px;
|
||||
}
|
||||
.fxos11 x-layout header a {
|
||||
float: right;
|
||||
}
|
||||
x-layout > header,
|
||||
x-layout > footer {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
x-layout > header {
|
||||
top: 0;
|
||||
}
|
||||
x-layout > section {
|
||||
padding: 45px 0 75px;
|
||||
}
|
||||
x-layout > footer {
|
||||
bottom: 0;
|
||||
}
|
||||
x-appbar h1 {
|
||||
display: none;
|
||||
}
|
||||
x-appbar h1:last-of-type {
|
||||
display: block;
|
||||
}
|
||||
x-appbar > a {
|
||||
cursor: pointer;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
min-width: 45px;
|
||||
background: transparent;
|
||||
}
|
||||
x-appbar > a:hover {
|
||||
background-color: #00405d;
|
||||
}
|
||||
x-appbar > a::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
x-tabbar-tab a {
|
||||
color: #fff;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
x-tabbar-tab[selected] {
|
||||
border-bottom: 0.3rem solid #0ac;
|
||||
}
|
||||
x-tabbar-tab[selected] a {
|
||||
color: #0ac;
|
||||
}
|
||||
.my-podcasts {
|
||||
margin: 5px 0;
|
||||
}
|
||||
.my-podcasts li {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
height: 150px;
|
||||
margin: 0 2.5% 20px;
|
||||
width: 45%;
|
||||
}
|
||||
.my-podcasts li img {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
.my-podcasts li .no-cover {
|
||||
background: #dedede;
|
||||
border: 1px solid #000;
|
||||
color: #000;
|
||||
display: inline-block;
|
||||
font-size: 1.2em;
|
||||
min-height: 100px;
|
||||
padding: 30px 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.episodes .episode {
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid #bbb;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
height: 100%;
|
||||
height: 60px;
|
||||
padding: 5px;
|
||||
}
|
||||
.episodes .episode:active {
|
||||
background: #dedede;
|
||||
}
|
||||
.episodes .episode.is-new {
|
||||
background: rgba(49,49,49,0.1);
|
||||
}
|
||||
.episodes .name {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
line-height: 1.3em;
|
||||
padding: 10px 0 0 5px;
|
||||
width: 80%;
|
||||
}
|
||||
.episodes .actions {
|
||||
float: right;
|
||||
font-size: 20px;
|
||||
margin: 15px 20px 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#player {
|
||||
background: #ddd;
|
||||
border-top: #010101 1px solid;
|
||||
font-size: 18px;
|
||||
opacity: 0;
|
||||
transition: 300ms linear all;
|
||||
}
|
||||
#player progress {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
background: #0ac;
|
||||
height: 25px;
|
||||
}
|
||||
#player progress::-moz-progress-bar {
|
||||
background: #00202f;
|
||||
}
|
||||
#player #time-elapsed,
|
||||
#player #time-remaining {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
color: #fff;
|
||||
}
|
||||
#player #time-elapsed {
|
||||
left: 5px;
|
||||
}
|
||||
#player #time-remaining {
|
||||
right: 5px;
|
||||
}
|
||||
#player .episode-name {
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
#player .player-controls {
|
||||
padding-bottom: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
#player .player-controls .forward,
|
||||
#player .player-controls .backward {
|
||||
cursor: pointer;
|
||||
font-size: 30px;
|
||||
padding: 0 15px;
|
||||
color: #777;
|
||||
}
|
||||
#player .player-controls .play-pause {
|
||||
cursor: pointer;
|
||||
font-size: 30px;
|
||||
color: #444;
|
||||
}
|
||||
#player.is-populated {
|
||||
opacity: 1;
|
||||
transition: 300ms linear all;
|
||||
}
|
||||
|
||||
.cover-image {
|
||||
display: block;
|
||||
max-height: 150px;
|
||||
}
|
||||
.cover-image::after {
|
||||
clear: both;
|
||||
content: "";
|
||||
display: block;
|
||||
}
|
||||
.podcast {
|
||||
padding: 5px;
|
||||
}
|
||||
.error {
|
||||
color: #ff4500;
|
||||
}
|
||||
|
||||
#search-input {
|
||||
width: 75%;
|
||||
}
|
||||
.results {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.results .podcast {
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
height: 150px;
|
||||
overflow: hidden;
|
||||
padding: 2.5%;
|
||||
text-align: center;
|
||||
width: 45%;
|
||||
}
|
||||
.results .podcast:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
margin: auto auto;
|
||||
width: 50px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
}
|
||||
.spinner > div {
|
||||
background-color: #333;
|
||||
height: 100%;
|
||||
width: 6px;
|
||||
display: inline-block;
|
||||
-webkit-animation: stretchdelay 1.2s infinite ease-in-out;
|
||||
animation: stretchdelay 1.2s infinite ease-in-out;
|
||||
}
|
||||
.spinner .rect2 {
|
||||
-webkit-animation-delay: -1.1s;
|
||||
animation-delay: -1.1s;
|
||||
}
|
||||
.spinner .rect3 {
|
||||
-webkit-animation-delay: -1s;
|
||||
animation-delay: -1s;
|
||||
}
|
||||
.spinner .rect4 {
|
||||
-webkit-animation-delay: -0.9s;
|
||||
animation-delay: -0.9s;
|
||||
}
|
||||
.spinner .rect5 {
|
||||
-webkit-animation-delay: -0.8s;
|
||||
animation-delay: -0.8s;
|
||||
}
|
||||
@-webkit-keyframes stretchdelay {
|
||||
0%, 40%, 100% {
|
||||
-webkit-transform: scaleY(0.4);
|
||||
}
|
||||
20% {
|
||||
-webkit-transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes stretchdelay {
|
||||
0%, 40%, 100% {
|
||||
transform: scaleY(0.4);
|
||||
-webkit-transform: scaleY(0.4);
|
||||
}
|
||||
20% {
|
||||
transform: scaleY(1);
|
||||
-webkit-transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes stretchdelay {
|
||||
0%, 40%, 100% {
|
||||
transform: scaleY(0.4);
|
||||
-webkit-transform: scaleY(0.4);
|
||||
}
|
||||
20% {
|
||||
transform: scaleY(1);
|
||||
-webkit-transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@-o-keyframes stretchdelay {
|
||||
0%, 40%, 100% {
|
||||
transform: scaleY(0.4);
|
||||
-webkit-transform: scaleY(0.4);
|
||||
}
|
||||
20% {
|
||||
transform: scaleY(1);
|
||||
-webkit-transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@keyframes stretchdelay {
|
||||
0%, 40%, 100% {
|
||||
transform: scaleY(0.4);
|
||||
-webkit-transform: scaleY(0.4);
|
||||
}
|
||||
20% {
|
||||
transform: scaleY(1);
|
||||
-webkit-transform: scaleY(1);
|
||||
}
|
||||
}
|
25
.travis.yml
|
@ -1,6 +1,23 @@
|
|||
before_install:
|
||||
- npm install -g bower grunt-cli
|
||||
- bower install
|
||||
---
|
||||
language: node_js
|
||||
node_js:
|
||||
- '0.10'
|
||||
- "0.12"
|
||||
|
||||
sudo: false
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
|
||||
before_install:
|
||||
- export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH
|
||||
- "npm config set spin false"
|
||||
- "npm install -g npm@^2"
|
||||
|
||||
install:
|
||||
- npm install -g bower
|
||||
- npm install
|
||||
- bower install
|
||||
|
||||
script:
|
||||
- npm test
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"ignore_dirs": ["tmp"]
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/* global require, module */
|
||||
|
||||
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
|
||||
|
||||
var app = new EmberApp({
|
||||
wrapInEval: false
|
||||
});
|
||||
|
||||
app.import('bower_components/i18n-js/app/assets/javascripts/i18n.js');
|
||||
|
||||
// Use `app.import` to add additional libraries to the generated
|
||||
// output files.
|
||||
//
|
||||
// If you need to use different assets in different
|
||||
// environments, specify an object as the first parameter. That
|
||||
// object's keys should be the environment name and the values
|
||||
// should be the asset to use in that environment.
|
||||
//
|
||||
// If the library that you are including contains AMD or ES6
|
||||
// modules that you would like to import into your application
|
||||
// please specify an object with the list of modules as keys
|
||||
// along with the exports of each module as its value.
|
||||
|
||||
module.exports = app.toTree();
|
|
@ -0,0 +1,53 @@
|
|||
# Ember-hifi
|
||||
|
||||
This README outlines the details of collaborating on this Ember application.
|
||||
A short introduction of this app could easily go here.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You will need the following things properly installed on your computer.
|
||||
|
||||
* [Git](http://git-scm.com/)
|
||||
* [Node.js](http://nodejs.org/) (with NPM)
|
||||
* [Bower](http://bower.io/)
|
||||
* [Ember CLI](http://www.ember-cli.com/)
|
||||
* [PhantomJS](http://phantomjs.org/)
|
||||
|
||||
## Installation
|
||||
|
||||
* `git clone <repository-url>` this repository
|
||||
* change into the new directory
|
||||
* `npm install`
|
||||
* `bower install`
|
||||
|
||||
## Running / Development
|
||||
|
||||
* `ember server`
|
||||
* Visit your app at [http://localhost:4200](http://localhost:4200).
|
||||
|
||||
### Code Generators
|
||||
|
||||
Make use of the many generators for code, try `ember help generate` for more details
|
||||
|
||||
### Running Tests
|
||||
|
||||
* `ember test`
|
||||
* `ember test --server`
|
||||
|
||||
### Building
|
||||
|
||||
* `ember build` (development)
|
||||
* `ember build --environment production` (production)
|
||||
|
||||
### Deploying
|
||||
|
||||
Specify what it takes to deploy your app.
|
||||
|
||||
## Further Reading / Useful Links
|
||||
|
||||
* [ember.js](http://emberjs.com/)
|
||||
* [ember-cli](http://www.ember-cli.com/)
|
||||
* Development Browser Extensions
|
||||
* [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
|
||||
* [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import DS from 'ember-data';
|
||||
|
||||
export default DS.LSAdapter.extend({
|
||||
databaseName: 'hifi',
|
||||
version: 2,
|
||||
migrations: function() {
|
||||
this.addModel('podcast');
|
||||
this.addModel('episode');
|
||||
}
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
import Ember from 'ember';
|
||||
import Resolver from 'ember/resolver';
|
||||
import loadInitializers from 'ember/load-initializers';
|
||||
import config from './config/environment';
|
||||
|
||||
var App;
|
||||
|
||||
Ember.MODEL_FACTORY_INJECTIONS = true;
|
||||
|
||||
App = Ember.Application.extend({
|
||||
modulePrefix: config.modulePrefix,
|
||||
podModulePrefix: config.podModulePrefix,
|
||||
Resolver: Resolver
|
||||
});
|
||||
|
||||
loadInitializers(App, config.modulePrefix);
|
||||
|
||||
export default App;
|
|
@ -0,0 +1,4 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
isPackaged: function() {
|
||||
return EmberHifi.get('isPackaged');
|
||||
}.property('application.isPackaged')
|
||||
});
|
|
@ -0,0 +1,24 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.ArrayController.extend({
|
||||
needs: ['player'],
|
||||
|
||||
sortAscending: false,
|
||||
sortProperties: ['datePublished'],
|
||||
selectedEpisode: null,
|
||||
|
||||
actions: {
|
||||
download: function(episode) {
|
||||
episode.download();
|
||||
},
|
||||
|
||||
setEpisode: function(episode) {
|
||||
this.set('selectedEpisode', episode);
|
||||
if (!episode.get('isDownloaded')) {
|
||||
this.get('controllers.player').send('setEpisode', episode);
|
||||
} else {
|
||||
this.get('controllers.player').send('setEpisode', episode);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
|
@ -0,0 +1,113 @@
|
|||
import Ember from 'ember';
|
||||
import timeStamper from 'ember-hifi/lib/timestamp';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
_hasAudio: function() {
|
||||
this.set('isPopulated', !!this.get('model').get('id'));
|
||||
}.observes('model'),
|
||||
isPopulated: false,
|
||||
progressBar: {
|
||||
max: 0,
|
||||
value: 0
|
||||
},
|
||||
setToPlayAfterLoaded: false,
|
||||
skipTime: 15, // Time, in seconds, to skip backward/forward.
|
||||
timeElapsed: '--:--',
|
||||
timeRemaining: '--:--',
|
||||
timeTotal: '--:--',
|
||||
|
||||
actions: {
|
||||
pause: function(episode) {
|
||||
clearTimeout(this._timeUpdateTimeout);
|
||||
clearTimeout(this._saveInBackgroundTimeout);
|
||||
Ember.$('#audio-player')[0].pause();
|
||||
|
||||
episode.set('playbackPosition', Ember.$('#audio-player')[0].currentTime);
|
||||
episode.set('isPlaying', false);
|
||||
episode.save();
|
||||
},
|
||||
|
||||
play: function(episode) {
|
||||
Ember.$('#audio-player')[0].play();
|
||||
episode.set('isPlaying', true);
|
||||
},
|
||||
|
||||
rewind: function(episode) {
|
||||
Ember.$('#audio-player')[0].currentTime -= this.get('skipTime');
|
||||
episode.set('playbackPosition', Ember.$('#audio-player')[0].currentTime);
|
||||
},
|
||||
|
||||
forward: function(episode) {
|
||||
Ember.$('#audio-player')[0].currentTime += this.get('skipTime');
|
||||
episode.set('playbackPosition', Ember.$('#audio-player')[0].currentTime);
|
||||
},
|
||||
|
||||
setEpisode: function(episode) {
|
||||
var _this = this;
|
||||
|
||||
this.set('model', episode);
|
||||
|
||||
if (this.get('model').get('isDownloaded')) {
|
||||
episode.blobURL().then(function(url) {
|
||||
_this.set('audio', url);
|
||||
_this.playAfterSet();
|
||||
});
|
||||
} else {
|
||||
this.set('audio', this.get('model').get('audioURL'));
|
||||
this.playAfterSet();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
playAfterSet: function() {
|
||||
var audio = Ember.$('#audio-player')[0];
|
||||
var _this = this;
|
||||
|
||||
Ember.$(audio).attr('src', this.get('audio'));
|
||||
|
||||
Ember.$(audio).bind('canplay', function() {
|
||||
Ember.$(this).unbind('canplay');
|
||||
|
||||
if (_this.get('model').get('playbackPosition')) {
|
||||
audio.currentTime = _this.get('model').get('playbackPosition');
|
||||
}
|
||||
|
||||
_this.updateTime();
|
||||
|
||||
_this.send('play', _this.get('model'));
|
||||
});
|
||||
|
||||
// this.updateTime();
|
||||
this._saveInBackground();
|
||||
},
|
||||
|
||||
updateTime: function() {
|
||||
var audio = Ember.$('#audio-player')[0];
|
||||
var _this = this;
|
||||
|
||||
this.set('progressBar.max', audio.duration);
|
||||
this.set('progressBar.value', audio.currentTime);
|
||||
|
||||
this.set('timeElapsed', timeStamper.formatTime(audio.currentTime));
|
||||
this.set('timeRemaining', timeStamper.formatTime(audio.duration - audio.currentTime));
|
||||
|
||||
this._timeUpdateTimeout = setTimeout(function() {
|
||||
_this.updateTime();
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
_saveInBackground: function() {
|
||||
var audio = Ember.$('#audio-player')[0];
|
||||
var _this = this;
|
||||
|
||||
this.get('model').set('playbackPosition', audio.currentTime);
|
||||
this.get('model').save();
|
||||
|
||||
this._saveInBackgroundTimeout = setTimeout(function() {
|
||||
_this._saveInBackground();
|
||||
}, 10000);
|
||||
}
|
||||
});
|
|
@ -0,0 +1,13 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
actions: {
|
||||
delete: function() {
|
||||
this.get('model').destroyRecord();
|
||||
this.transitionToRoute('podcasts');
|
||||
},
|
||||
update: function() {
|
||||
this.get('model').update();
|
||||
}
|
||||
}
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.ArrayController.extend({
|
||||
sortProperties: ['title']
|
||||
});
|
|
@ -0,0 +1,54 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
isAdding: false,
|
||||
isInErrorState: false,
|
||||
rssURL: '',
|
||||
actions: {
|
||||
create: function(url) {
|
||||
var self = this;
|
||||
|
||||
if (url) {
|
||||
self.set('rssURL', url);
|
||||
}
|
||||
|
||||
if (!self.get('rssURL') || !self.get('rssURL').length) {
|
||||
console.log('No rssUrl specified!');
|
||||
return;
|
||||
}
|
||||
|
||||
// If the URL entered doesn't have a protocol attached, make
|
||||
// sure one is added so we don't get an error (#43).
|
||||
if (!self.get('rssURL').match(/^http[s]?:\/\//i)) {
|
||||
self.set('rssURL', 'http://' + self.get('rssURL'));
|
||||
}
|
||||
|
||||
self.set('isAdding', true);
|
||||
|
||||
// var existingPodcast = self.store.find('podcast', {
|
||||
// rssURL: self.get('rssURL')
|
||||
// }).then(function(podcast) {
|
||||
// console.log('Podcast: ', podcast);
|
||||
// console.info('Podcast already exists', podcast.objectAt(0));
|
||||
|
||||
// self.set('isAdding', false);
|
||||
// self.set('rssURL', '');
|
||||
// self.transitionToRoute('podcast', podcast.objectAt(0));
|
||||
// }, function() {
|
||||
|
||||
var podcast = self.store.createRecord('podcast', {
|
||||
rssURL: self.get('rssURL')
|
||||
});
|
||||
|
||||
podcast.update().then(function() {
|
||||
self.set('isAdding', false);
|
||||
self.set('rssURL', '');
|
||||
self.transitionToRoute('podcast', podcast);
|
||||
}, function() {
|
||||
self.set('isAdding', false);
|
||||
self.set('isInErrorState', true);
|
||||
});
|
||||
// });
|
||||
}
|
||||
}
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
// import Ember from 'ember';
|
||||
// import I18n from 'I18n';
|
||||
|
||||
// export function t(params, hash) {
|
||||
// console.log('Params: ', params);
|
||||
// var _this = this;
|
||||
|
||||
// // Support variable interpolation for this string.
|
||||
// Object.keys(params).forEach(function(key) {
|
||||
// params[key] = Ember.Handlebars.get(_this, params[key], hash);
|
||||
// });
|
||||
|
||||
// return I18n.t(params, hash);
|
||||
// }
|
||||
|
||||
// export default Ember.HTMLBars.makeBoundHelper(t);
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>EmberHifi</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
{{content-for 'head'}}
|
||||
|
||||
<link rel="stylesheet" href="assets/vendor.css">
|
||||
<link rel="stylesheet" href="assets/ember-hifi.css">
|
||||
|
||||
{{content-for 'head-footer'}}
|
||||
</head>
|
||||
<body>
|
||||
{{content-for 'body'}}
|
||||
|
||||
<script src="assets/vendor.js"></script>
|
||||
<script src="assets/ember-hifi.js"></script>
|
||||
|
||||
{{content-for 'body-footer'}}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,40 @@
|
|||
'use strict';
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
const NUMBER_OF_PODCASTS_TO_GET = 1000;
|
||||
|
||||
export default function getRSS(url, callback) {
|
||||
return new Ember.RSVP.Promise(function(resolve, reject) {
|
||||
var jsonpCallback = EmberHifi.isPackaged ? '' : '&callback=?';
|
||||
|
||||
$.ajax({
|
||||
url: 'https://ajax.googleapis.com/ajax/' +
|
||||
'services/feed/load?v=1.0' + jsonpCallback +
|
||||
// TODO: Actually paginate results; for now we just get
|
||||
// "all" podcasts, presuming most podcasts have fewer
|
||||
// than 1,000 episodes.
|
||||
'&num=' + NUMBER_OF_PODCASTS_TO_GET + '&output=json_xml' +
|
||||
'&q=' + encodeURIComponent(url),
|
||||
dataType: 'json',
|
||||
success: function(response, xhr) {
|
||||
if (!response || !response.responseData) {
|
||||
console.error('Bad response', response);
|
||||
return reject(xhr);
|
||||
}
|
||||
|
||||
var xml = new DOMParser();
|
||||
var xmlString = response.responseData.xmlString;
|
||||
var xmlDoc = xml.parseFromString(xmlString, 'text/xml');
|
||||
|
||||
if (callback) {
|
||||
callback(xmlDoc);
|
||||
}
|
||||
resolve(xmlDoc);
|
||||
},
|
||||
error: function(error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
export default {
|
||||
formatTime: function(secs) {
|
||||
if (isNaN(secs)) {
|
||||
return '--:--';
|
||||
}
|
||||
|
||||
var hours = parseInt(secs / 3600, 10) % 24;
|
||||
var minutes = parseInt(secs / 60, 10) % 60;
|
||||
var seconds = parseInt(secs % 60, 10);
|
||||
|
||||
var time = (hours !== 0 ? hours + ':' : '') +
|
||||
(minutes < 10 ? '0' + minutes : minutes) + ':' +
|
||||
(seconds < 10 ? '0' + seconds : seconds);
|
||||
|
||||
return time;
|
||||
},
|
||||
|
||||
timestamp: function(date) {
|
||||
if (!date) {
|
||||
date = new Date();
|
||||
}
|
||||
|
||||
if (date instanceof Date !== true) {
|
||||
date = new Date(date);
|
||||
}
|
||||
|
||||
return Math.round(date.getTime() / 1000);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,164 @@
|
|||
import DS from 'ember-data';
|
||||
import Ember from 'ember';
|
||||
|
||||
export default DS.Model.extend({
|
||||
podcast: DS.belongsTo('podcast', {async: true}),
|
||||
|
||||
name: DS.attr('string'),
|
||||
audioURL: DS.attr('string'),
|
||||
audioLength: DS.attr('number'),
|
||||
playbackPosition: DS.attr('number'),
|
||||
playCount: DS.attr('number'),
|
||||
// audioFile: DS.attr('object'),
|
||||
guid: DS.attr('string'),
|
||||
|
||||
// Episode metadata from RSS.
|
||||
datePublished: DS.attr('number'),
|
||||
|
||||
// Episode download data; unavailable in hosted version for the time being.
|
||||
isDownloaded: DS.attr('boolean'),
|
||||
_chunkCount: DS.attr('number'),
|
||||
_chunkCountSaved: DS.attr('number'),
|
||||
_loadComplete: false,
|
||||
|
||||
isDownloading: false,
|
||||
isPlaying: false,
|
||||
|
||||
isNew: function() {
|
||||
return !this.get('playbackPosition') && !this.get('playCount');
|
||||
}.property('playbackPosition', 'playCount'),
|
||||
|
||||
blobURL: function() {
|
||||
var _this = this;
|
||||
|
||||
return new Ember.RSVP.Promise(function(resolve) {
|
||||
_this._assembleChunkData().then(function(blob) {
|
||||
resolve(window.URL.createObjectURL(blob));
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Download the episode for local playback.
|
||||
download: function(model) {
|
||||
this.set('isDownloading', true);
|
||||
this.set('_chunkCount', 0);
|
||||
this.set('_chunkCountSaved', 0);
|
||||
|
||||
var _this = this;
|
||||
var request = new XMLHttpRequest({mozSystem: true});
|
||||
|
||||
request.open('GET', this.get('audioURL'), true);
|
||||
request.responseType = 'moz-chunked-arraybuffer';
|
||||
|
||||
// request.addEventListener('load', );
|
||||
request.addEventListener('load', function() {
|
||||
console.log(request.readyState, request);
|
||||
if (request.readyState === 4) {
|
||||
// _this._setAudioType(_this.get('audioURL'));
|
||||
_this._loadComplete = true;
|
||||
}
|
||||
});
|
||||
|
||||
request.addEventListener('progress', function() {
|
||||
console.info('eventProgress', _this.get('_chunkCount'));
|
||||
localforage.setItem('ep:' + _this.get('id') +
|
||||
_this.get('_chunkCount'), request.response)
|
||||
.then(function() {
|
||||
// Increment our internal data chunk count.
|
||||
_this.incrementProperty('_chunkCountSaved');
|
||||
|
||||
if (_this.get('_chunkCount') ===
|
||||
_this.get('_chunkCountSaved') &&
|
||||
_this.get('_loadComplete')) {
|
||||
console.log('chunk data assembled');
|
||||
_this.set('isDownloading', false);
|
||||
_this.set('isDownloaded', true);
|
||||
// try {
|
||||
// setTimeout(function() {
|
||||
// _this.save();
|
||||
// }, 20);
|
||||
// } catch (e) {
|
||||
// console.error(e);
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
_this.incrementProperty('_chunkCount');
|
||||
});
|
||||
|
||||
request.addEventListener('error', function() {
|
||||
window.alert('Error downloading this episode. Please try again.');
|
||||
|
||||
// _this.trigger('download:cancel');
|
||||
});
|
||||
|
||||
request.send(null);
|
||||
},
|
||||
|
||||
// Because of limitations/platform bugs in b2g18 (what ships on
|
||||
// first-gen Firefox OS devices), we can't move around huge Blob
|
||||
// objects (particularly, we can't save them anywhere) without crashing
|
||||
// the app on a device from out of memory errors.
|
||||
//
|
||||
// This retrieves the smaller, more manageable chunks of data from
|
||||
// IndexedDB and assembles them into a Blob object we hand off to a
|
||||
// callback function. For some reason, B2G seems to cope just fine with
|
||||
// this very odd solution because it handles Blobs full of arrayBuffers
|
||||
// better than it saves large Blobs.
|
||||
//
|
||||
// This is a HACK and should be fixed by platform in the next release,
|
||||
// I hope.
|
||||
//
|
||||
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=873274
|
||||
// and: https://bugzilla.mozilla.org/show_bug.cgi?id=869812
|
||||
_assembleChunkData: function() {
|
||||
var audioBlobs = [];
|
||||
var chunkCount = this.get('_chunkCount');
|
||||
var _this = this;
|
||||
|
||||
return new Ember.RSVP.Promise(function(resolve) {
|
||||
function _walkChunks(chunkID) {
|
||||
if (chunkID === undefined) {
|
||||
chunkID = 0;
|
||||
}
|
||||
|
||||
if (chunkID < chunkCount) {
|
||||
localforage.getItem('ep:' + _this.get('id') + chunkID)
|
||||
.then(function(blob) {
|
||||
console.info('ep:' + _this.get('id') + chunkID, blob);
|
||||
audioBlobs.push(blob);
|
||||
_walkChunks(chunkID + 1);
|
||||
});
|
||||
} else {
|
||||
var blob = new Blob(audioBlobs, {type: 'mp3'});
|
||||
resolve(blob);
|
||||
}
|
||||
}
|
||||
|
||||
_walkChunks();
|
||||
});
|
||||
},
|
||||
|
||||
// Set the audio type based on the responseType (or filename) of this
|
||||
// episode's enclosure file/URL.
|
||||
_setAudioType: function(audioURL, event) {
|
||||
// TODO: Make this better.
|
||||
var type;
|
||||
|
||||
try {
|
||||
type = event.target.response.type.split('/')[1];
|
||||
} catch (e) {
|
||||
// Try to extract the type of this file from its filename.
|
||||
var enclosureArray = audioURL.split('.');
|
||||
type = enclosureArray[enclosureArray.length - 1];
|
||||
}
|
||||
|
||||
// Assume "mpeg" = MP3, for now. Kinda hacky.
|
||||
if (type === 'mpeg') {
|
||||
type = 'mp3';
|
||||
}
|
||||
|
||||
this.set('type', type);
|
||||
// this.save();
|
||||
}
|
||||
});
|
|
@ -0,0 +1,160 @@
|
|||
import DS from 'ember-data';
|
||||
import Ember from 'ember';
|
||||
import timeStamper from 'ember-hifi/lib/timestamp';
|
||||
import getRSS from 'ember-hifi/lib/rss';
|
||||
|
||||
export default DS.Model.extend({
|
||||
episodes: DS.hasMany('episode', {async: true}),
|
||||
|
||||
title: DS.attr('string'),
|
||||
description: DS.attr('string'),
|
||||
rssURL: DS.attr('string'),
|
||||
lastUpdated: DS.attr('number'),
|
||||
lastPlayed: DS.attr('number'),
|
||||
|
||||
coverImageBlob: DS.attr('string'),
|
||||
coverImageURL: DS.attr('string'),
|
||||
|
||||
coverImage: function() {
|
||||
if (this.get('coverImageURL')) {
|
||||
return this.get('coverImageURL');
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}.property('coverImageBlob', 'coverImageURL'),
|
||||
|
||||
destroyRecord: function() {
|
||||
this.get('episodes').forEach(function(episode) {
|
||||
episode.destroyRecord();
|
||||
});
|
||||
return this._super();
|
||||
},
|
||||
|
||||
getCoverImage: function() {
|
||||
if (!this.get('coverImageURL')) {
|
||||
console.debug('No coverImageURL found; skipping.');
|
||||
return;
|
||||
}
|
||||
|
||||
var _this = this;
|
||||
|
||||
var request = new XMLHttpRequest({mozSystem: true});
|
||||
|
||||
request.open('GET', this.get('coverImageURL'), true);
|
||||
request.responseType = 'arraybuffer';
|
||||
|
||||
request.addEventListener('load', function() {
|
||||
_this.set('coverImageBlob', request.response);
|
||||
_this.save();
|
||||
});
|
||||
|
||||
try {
|
||||
request.send(null);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
},
|
||||
|
||||
// Update this podcast from the RSS feed, but don't download any
|
||||
// new episodes by default.
|
||||
update: function() {
|
||||
var _this = this;
|
||||
|
||||
console.info('Updating podcast:' + this.get('id'));
|
||||
return new Ember.RSVP.Promise(function(resolve, reject) {
|
||||
// _this.getCoverImage();
|
||||
|
||||
// Update last updated time so we aren't constantly looking
|
||||
// for new episodes ;-)
|
||||
_this.set('lastUpdated', timeStamper.timestamp());
|
||||
|
||||
getRSS(_this.get('rssURL')).then(function(result) {
|
||||
var $xml = $(result);
|
||||
var $channel = $xml.find('channel');
|
||||
var $items = $xml.find('item');
|
||||
|
||||
if (!$xml.length || !$xml.find('item').length) {
|
||||
// If we can't make sense of this podcast's feed, we delete
|
||||
// it and inform the user of the error.
|
||||
window.alert('Error downloading podcast feed.');
|
||||
return;
|
||||
}
|
||||
|
||||
_this.set('title', $channel.find('title').eq(0).text());
|
||||
_this.set('description', $channel.find('description')
|
||||
.eq(0).text());
|
||||
_this.set('coverImageURL', $channel.find('itunes\\:image')
|
||||
.attr('href'));
|
||||
|
||||
console.log('Podcast record after setting data: ', _this);
|
||||
|
||||
_this.get('episodes').then(function(episodes) {
|
||||
var itemsSaved = 0;
|
||||
$items.each(function(i, episode) {
|
||||
var guid = $(episode).find('guid').text();
|
||||
|
||||
if (episodes.filterBy('guid', guid).length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var oldImageURL = _this.get('coverImageURL');
|
||||
|
||||
// Use the latest artwork for the cover image.
|
||||
var episodeImageURL = $(episode).find('itunes\\:image')
|
||||
.attr('href');
|
||||
if (i === 0 && episodeImageURL !== oldImageURL) {
|
||||
_this.set('coverImageURL', episodeImageURL);
|
||||
}
|
||||
|
||||
// If the cover image has changed (or this podcast is
|
||||
// new) we update the cover image.
|
||||
if (!oldImageURL ||
|
||||
oldImageURL !== _this.get('coverImageURL')) {
|
||||
// _this.getCoverImage();
|
||||
}
|
||||
|
||||
var e = _this.store.createRecord('episode', {
|
||||
guid: guid,
|
||||
audioURL: $(episode).find('enclosure').attr('url'),
|
||||
datePublished: timeStamper.timestamp(
|
||||
$(episode).find('pubDate').text()
|
||||
),
|
||||
name: $(episode).find('title').text(),
|
||||
podcast: _this
|
||||
});
|
||||
|
||||
// Add this episode to the list of objects; this will
|
||||
// cause it to appear in any existing lists.
|
||||
e.save();
|
||||
episodes.pushObject(e);
|
||||
|
||||
itemsSaved++;
|
||||
|
||||
if ($items.length === i + 1) {
|
||||
console.info('Updated podcast:' + _this.get('id'),
|
||||
itemsSaved + ' new episodes.');
|
||||
var saved = true;
|
||||
_this.save().then(resolve);
|
||||
}
|
||||
});
|
||||
|
||||
if (!itemsSaved && !$items.length && !saved) {
|
||||
console.info('Updated podcast:' + _this.get('id'),
|
||||
itemsSaved + ' new episodes.');
|
||||
_this.save().then(resolve);
|
||||
}
|
||||
});
|
||||
}, function(error) {
|
||||
console.error('Could not download podcast', error);
|
||||
_this.destroyRecord().then(reject);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_autoUpdate: function() {
|
||||
if (this.get('lastUpdated') + 3600 < timeStamper.timestamp()) {
|
||||
console.debug('Auto update for:' + this.get('title'));
|
||||
this.update();
|
||||
}
|
||||
}.observes('lastUpdated').on('init')
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
import Ember from 'ember';
|
||||
import config from './config/environment';
|
||||
|
||||
var Router = Ember.Router.extend({
|
||||
location: config.locationType
|
||||
});
|
||||
|
||||
Router.map(function() {
|
||||
this.route('search');
|
||||
|
||||
this.route('podcasts', { path: '/podcasts' }, function() {
|
||||
this.route('new');
|
||||
});
|
||||
|
||||
this.route('podcast', { path: '/podcast/:podcast_id'});
|
||||
});
|
||||
|
||||
export default Router;
|
|
@ -0,0 +1,7 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
model: function() {
|
||||
return this.store;
|
||||
}
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
redirect: function() {
|
||||
this.transitionTo('podcasts');
|
||||
}
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
model: function(params) {
|
||||
return this.store.find('podcast', params.podcast_id);
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
model: function() {
|
||||
return this.get('store').findAll('podcast');
|
||||
}
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
import DS from 'ember-data';
|
||||
|
||||
export default DS.LSSerializer.extend({
|
||||
serializeHasMany: function(snapshot, json, relationship) {
|
||||
var key = relationship.key;
|
||||
var payloadKey = this.keyForRelationship ? this.keyForRelationship(key, "hasMany") : key;
|
||||
var relationshipType = snapshot.type.determineRelationshipType(relationship, this.store);
|
||||
|
||||
if (relationshipType === 'manyToNone' ||
|
||||
relationshipType === 'manyToMany' ||
|
||||
relationshipType === 'manyToOne') {
|
||||
json[payloadKey] = snapshot.hasMany(key, { ids: true });
|
||||
// TODO support for polymorphic manyToNone and manyToMany relationships
|
||||
}
|
||||
}
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
<h1><a href="/podcasts">High Fidelity</a></h1>
|
||||
|
||||
{{outlet}}
|
|
@ -0,0 +1,37 @@
|
|||
<div class="episodes">
|
||||
|
||||
<audio id="audio-player" preload="auto" mozaudiochannel="content"></audio>
|
||||
|
||||
{{render "player"}}
|
||||
|
||||
{{#each episode in model}}
|
||||
<div {{action "setEpisode" episode}} {{bind-attr class=":episode isNew"}}>
|
||||
<div class="name">
|
||||
{{#if isNew}}
|
||||
<strong>{{episode.new}}</strong>
|
||||
{{/if}}
|
||||
{{model.name}} {{name}} {{episode.name}}
|
||||
</div>
|
||||
|
||||
{{!-- Commented out while we are streaming-only. This code exposes
|
||||
download/downloading/play/stream UI, but for now we're streaming
|
||||
only so we don't show anything.
|
||||
{{#if HighFidelity.isPackaged}}
|
||||
<div class="actions">
|
||||
{{#if isDownloaded}}
|
||||
<i class="fa fa-play-circle"></i>
|
||||
{{else}}
|
||||
{{#if isDownloading}}
|
||||
<i class="fa fa-spinner fa-spin"></i>
|
||||
{{else}}
|
||||
<i class="fa fa-cloud-download" {{action download this}}></i>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
--}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{render "spinner"}}
|
||||
{{/each}}
|
||||
</div>
|
|
@ -0,0 +1,33 @@
|
|||
<div id="player" {{bind-attr class="isPopulated"}}>
|
||||
<div id="time-info">
|
||||
<progress id="audio-progress" {{bind-attr max=progressBar.max}}
|
||||
{{bind-attr value=progressBar.value}}>
|
||||
</progress>
|
||||
|
||||
<span id="time-elapsed">{{timeElapsed}}</span>
|
||||
<span id="time-remaining">{{timeRemaining}}</span>
|
||||
</div>
|
||||
|
||||
<div class="episode-name">{{model.name}}</div>
|
||||
|
||||
<div class="player-controls">
|
||||
<a {{action "rewind" model}} class="backward">
|
||||
<i class="fa fa-backward"></i>
|
||||
{{fa-icon "backward"}}
|
||||
</a>
|
||||
|
||||
{{#if model.isPlaying}}
|
||||
<a {{action "pause" model}} class="play-pause">
|
||||
{{fa-icon "pause"}}
|
||||
</a>
|
||||
{{else}}
|
||||
<a {{action "play" model}} class="play-pause">
|
||||
{{fa-icon "play"}}
|
||||
</a>
|
||||
{{/if}}
|
||||
|
||||
<a {{action "forward" model}} class="forward">
|
||||
{{fa-icon "forward"}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,12 @@
|
|||
<div class="podcast">
|
||||
<img class="cover-image" {{bind-attr src=model.coverImageURL}}
|
||||
{{bind-attr alt=model.title}}>
|
||||
|
||||
<p>{{model.description}} {{model.lastUpdated}}</p>
|
||||
|
||||
<button {{action "delete"}}>Unsubscribe</button>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
{{render "episodes" model.episodes}}
|
|
@ -0,0 +1,16 @@
|
|||
{{#link-to 'podcasts.new'}}Add New Podcast{{/link-to}}
|
||||
<h3>My Podcasts</h3>
|
||||
<ul class="my-podcasts">
|
||||
{{#each podcast in model tagName=ul className="my-podcasts"}}
|
||||
<li>
|
||||
{{#link-to 'podcast' podcast class="cover"}}
|
||||
{{#if coverImage}}
|
||||
<img {{bind-attr src=podcast.coverImage}} {{bind-attr alt=podcast.title}}>
|
||||
{{else}}
|
||||
<span class="no-cover">{{podcast.title}}</span>
|
||||
{{/if}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{outlet}}
|
|
@ -0,0 +1,30 @@
|
|||
<h2>{{podcast.addRSSFeed}}</h2>
|
||||
|
||||
{{#if isInErrorState}}
|
||||
<div class="error">
|
||||
<p>Encountered an error while adding Podcast.</p>
|
||||
<p>Is the Podcast URL valid?</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{input type="url" value=rssURL placeholder="Podcast URL"}}
|
||||
<button {{action 'create'}}>{{podcast.add}}</button>
|
||||
|
||||
<h2>{{podcast.newToPodcasts}}</h2>
|
||||
<h3>{{podcast.recommendations}}</h3>
|
||||
|
||||
<h4>The Cracked Podcast</h4>
|
||||
<img alt="The Cracked Podcast" class="cover cover-image"
|
||||
{{action 'create' "http://rss.earwolf.com/the-cracked-podcast"}}
|
||||
src="http://cdn.earwolf.com/wp-content/uploads/2013/08/EAR_CrackedPodcast_1600x1600_Cover_Final.jpg">
|
||||
|
||||
<h4>Hello Internet</h4>
|
||||
<img alt="Hello Internet" class="cover cover-image"
|
||||
{{action 'create' "http://feeds.podtrac.com/m2lTaLRx8AWb"}}
|
||||
src="http://static.squarespace.com/static/52d66949e4b0a8cec3bcdd46/t/52ebf67fe4b0f4af2a4502d8/1391195777839/1500w/Hello%20Internet.003.png">
|
||||
|
||||
{{#if isAdding}}
|
||||
<div class="full-screen">
|
||||
{{render "spinner"}}
|
||||
</div>
|
||||
{{/if}}
|
|
@ -0,0 +1,7 @@
|
|||
<div class="spinner">
|
||||
<div class="rect1"></div>
|
||||
<div class="rect2"></div>
|
||||
<div class="rect3"></div>
|
||||
<div class="rect4"></div>
|
||||
<div class="rect5"></div>
|
||||
</div>
|
|
@ -0,0 +1,221 @@
|
|||
import I18n from 'I18n';
|
||||
|
||||
I18n.defaultLocale = "en-US";
|
||||
I18n.locale = window.navigator.language || 'en-US';
|
||||
I18n.fallbacks = true;
|
||||
I18n.translations = {
|
||||
// English by @tofumatt
|
||||
en: {
|
||||
app: {
|
||||
title: 'Podcasts',
|
||||
},
|
||||
episode: {
|
||||
episodes: 'Episodes',
|
||||
new: 'New:',
|
||||
},
|
||||
podcast: {
|
||||
add: 'Add',
|
||||
addOne: 'Want to add one?',
|
||||
addRSSFeed: 'Add RSS Feed',
|
||||
newToPodcasts: 'New to Podcasts?',
|
||||
noneFound: 'No podcasts found.',
|
||||
recommendations: 'Check out our recommendations:',
|
||||
},
|
||||
search: {
|
||||
find: 'Find',
|
||||
noResults: 'No results.',
|
||||
placeholder: 'Podcast Name or Keywords',
|
||||
searchForAPodcast: 'Search for a Podcast',
|
||||
subscribe: 'Subscribe to {{podcast}}?',
|
||||
},
|
||||
tabs: {
|
||||
myPodcasts: 'My Podcasts',
|
||||
popular: 'Popular',
|
||||
search: 'Search',
|
||||
},
|
||||
},
|
||||
|
||||
// Esperanto by @Airon90
|
||||
eo: {
|
||||
app: {
|
||||
title: 'Podkastoj',
|
||||
},
|
||||
episode: {
|
||||
episodes: 'Epizodoj',
|
||||
new: 'Nova:',
|
||||
},
|
||||
podcast: {
|
||||
add: 'Aldoni',
|
||||
addOne: 'Ĉu vi volas aldoni novan?',
|
||||
addRSSFeed: 'Aldoni RSS-fluon',
|
||||
newToPodcasts: 'Ĉu malkutimas podkastojn?',
|
||||
noneFound: 'Neniu podkasto trovata.',
|
||||
recommendations: 'Kontrolu niajn rekomendojn:',
|
||||
},
|
||||
search: {
|
||||
find: 'Trovi',
|
||||
noResults: 'Neniu rezulto.',
|
||||
placeholder: 'Nomo de podkasto aŭ ŝlosilvorto',
|
||||
searchForAPodcast: 'Serĉi podkaston',
|
||||
subscribe: 'Ĉu aliĝi al {{podcast}}?',
|
||||
},
|
||||
tabs: {
|
||||
myPodcasts: 'Miaj podkastoj',
|
||||
popular: 'Popularaj',
|
||||
search: 'Serĉi',
|
||||
},
|
||||
},
|
||||
|
||||
// French by @AntoineTurmel
|
||||
fr: {
|
||||
app: {
|
||||
title: 'Podcasts',
|
||||
},
|
||||
episode: {
|
||||
episodes: "Episodes",
|
||||
new: 'nouveau:',
|
||||
},
|
||||
podcast: {
|
||||
add: 'Ajouter',
|
||||
addOne: 'Voulez-vous en ajouter un?',
|
||||
addRSSFeed: 'Ajouter un flux RSS',
|
||||
newToPodcasts: 'Vous ne connaissez pas de Podcasts?',
|
||||
noneFound: 'Aucun podcast trouvé.',
|
||||
recommendations: 'Voici nos recommandations:',
|
||||
},
|
||||
search: {
|
||||
find: 'chercher',
|
||||
noResults: 'Aucun résultat.',
|
||||
placeholder: 'Nom du podcast ou mots-clés',
|
||||
searchForAPodcast: 'Trouver un podcast',
|
||||
subscribe: 'S\'abonner à {{podcast}}?',
|
||||
},
|
||||
tabs: {
|
||||
myPodcasts: 'mes podcasts',
|
||||
popular: 'populaire',
|
||||
search: 'recherche',
|
||||
},
|
||||
},
|
||||
|
||||
// Italian by @Airon90
|
||||
it: {
|
||||
app: {
|
||||
title: 'Podcast',
|
||||
},
|
||||
episode: {
|
||||
episodes: 'Episodi',
|
||||
new: 'Nuovo:',
|
||||
},
|
||||
podcast: {
|
||||
add: 'Aggiungi',
|
||||
addOne: 'Aggiungi uno nuovo?',
|
||||
addRSSFeed: 'Aggiungi feed RSS',
|
||||
newToPodcasts: 'Nuovo ai podcast?',
|
||||
noneFound: 'Nessun podcast trovato.',
|
||||
recommendations: 'Controlla i nostri consigli:',
|
||||
},
|
||||
search: {
|
||||
find: 'Trova',
|
||||
noResults: 'Nessun risultato.',
|
||||
placeholder: 'Nome del podcast o parola chiave',
|
||||
searchForAPodcast: 'Cerca un podcast',
|
||||
subscribe: 'Vuoi abbonarti a {{podcast}}?',
|
||||
},
|
||||
tabs: {
|
||||
myPodcasts: 'I miei podcast',
|
||||
popular: 'Popolari',
|
||||
search: 'Cerca',
|
||||
},
|
||||
},
|
||||
|
||||
// Polish by @MaciejCzyzewski
|
||||
pl: {
|
||||
app: {
|
||||
title: 'Podcasty', // Transmisje
|
||||
},
|
||||
episode: {
|
||||
episodes: 'Epizody', // Fragmenty
|
||||
new: 'Nowe:',
|
||||
},
|
||||
podcast: {
|
||||
add: 'Dodaj',
|
||||
addOne: 'Chcesz jedno dodać?',
|
||||
addRSSFeed: 'Dodaj źródło RSS',
|
||||
newToPodcasts: 'Nowe do podcastu?',
|
||||
noneFound: 'Nie znaleziono podcastów.',
|
||||
recommendations: 'Sprawdź nasze rekomendacje:',
|
||||
},
|
||||
search: {
|
||||
find: 'Szukaj',
|
||||
noResults: 'Brak wyników.',
|
||||
placeholder: 'Podcast tytuł albo słowo kluczowe',
|
||||
searchForAPodcast: 'Szukaj w podcastach',
|
||||
subscribe: 'Subskrybuj {{podcast}}?',
|
||||
},
|
||||
tabs: {
|
||||
myPodcasts: 'Moje Podcasty',
|
||||
popular: 'Popularne',
|
||||
search: 'Szukaj',
|
||||
},
|
||||
},
|
||||
// galego by @xmgz
|
||||
gl: {
|
||||
app: {
|
||||
title: 'Podcasts',
|
||||
},
|
||||
episode: {
|
||||
episodes: 'Episodios',
|
||||
new: 'Novo:',
|
||||
},
|
||||
podcast: {
|
||||
add: 'Engadir',
|
||||
addOne: 'Quere engadir un?',
|
||||
addRSSFeed: 'Engdir fonte RSS',
|
||||
newToPodcasts: 'Novo nos podcast?',
|
||||
noneFound: 'Non se atoparon podcast.',
|
||||
recommendations: 'Mire as nosas recomendacións:',
|
||||
},
|
||||
search: {
|
||||
find: 'Buscar',
|
||||
noResults: 'Sen resultados.',
|
||||
placeholder: 'Nome do podcast ou palabras chave',
|
||||
searchForAPodcast: 'Buscar un podcast',
|
||||
subscribe: 'Suscribirse a {{podcast}}?',
|
||||
},
|
||||
tabs: {
|
||||
myPodcasts: 'Os meus podcast',
|
||||
popular: 'Popular',
|
||||
search: 'Buscar',
|
||||
},
|
||||
},
|
||||
// spanish by @xmgz
|
||||
es: {
|
||||
app: {
|
||||
title: 'Podcasts',
|
||||
},
|
||||
episode: {
|
||||
episodes: 'Episodios',
|
||||
new: 'Nuevo:',
|
||||
},
|
||||
podcast: {
|
||||
add: 'Añadir',
|
||||
addOne: 'Desea añadir uno',
|
||||
addRSSFeed: 'Añadir fuente RSS',
|
||||
newToPodcasts: 'Nuevo en los podcast?',
|
||||
noneFound: 'No se encontraron podcast.',
|
||||
recommendations: 'Estas son nuestras recomendaciones:',
|
||||
},
|
||||
search: {
|
||||
find: 'Buscar',
|
||||
noResults: 'Sin resultados.',
|
||||
placeholder: 'Nombre del podcast o palabras clave',
|
||||
searchForAPodcast: 'Buscar un podcast',
|
||||
subscribe: 'Suscribirse a {{podcast}}?',
|
||||
},
|
||||
tabs: {
|
||||
myPodcasts: 'Mis podcast',
|
||||
popular: 'Popular',
|
||||
search: 'Buscar',
|
||||
},
|
||||
},
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "ember-hifi",
|
||||
"dependencies": {
|
||||
"ember": "1.13.3",
|
||||
"ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3",
|
||||
"ember-cli-test-loader": "ember-cli-test-loader#0.1.3",
|
||||
"ember-data": "1.13.5",
|
||||
"ember-load-initializers": "ember-cli/ember-load-initializers#0.1.5",
|
||||
"ember-qunit": "0.4.1",
|
||||
"ember-qunit-notifications": "0.0.7",
|
||||
"ember-resolver": "~0.1.18",
|
||||
"jquery": "^1.11.1",
|
||||
"loader.js": "ember-cli/loader.js#3.2.0",
|
||||
"qunit": "~1.17.1",
|
||||
"font-awesome": "~4.3.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/* jshint node: true */
|
||||
|
||||
module.exports = function(environment) {
|
||||
var ENV = {
|
||||
modulePrefix: 'ember-hifi',
|
||||
environment: environment,
|
||||
baseURL: '/',
|
||||
locationType: 'auto',
|
||||
EmberENV: {
|
||||
FEATURES: {
|
||||
// Here you can enable experimental features on an ember canary build
|
||||
// e.g. 'with-controller': true
|
||||
}
|
||||
},
|
||||
|
||||
APP: {
|
||||
// Here you can pass flags/options to your application instance
|
||||
// when it is created
|
||||
},
|
||||
contentSecurityPolicy: {
|
||||
'default-src': "'none'",
|
||||
'script-src': "'self' 'unsafe-eval' https://ajax.googleapis.com/",
|
||||
'font-src': "'self'",
|
||||
'connect-src': "'self'",
|
||||
'img-src': "'self'",
|
||||
'style-src': "'self'",
|
||||
'media-src': "'self'"
|
||||
}
|
||||
};
|
||||
|
||||
if (environment === 'development') {
|
||||
// ENV.APP.LOG_RESOLVER = true;
|
||||
// ENV.APP.LOG_ACTIVE_GENERATION = true;
|
||||
// ENV.APP.LOG_TRANSITIONS = true;
|
||||
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
|
||||
// ENV.APP.LOG_VIEW_LOOKUPS = true;
|
||||
}
|
||||
|
||||
if (environment === 'test') {
|
||||
// Testem prefers this...
|
||||
ENV.baseURL = '/';
|
||||
ENV.locationType = 'none';
|
||||
|
||||
// keep test console output quieter
|
||||
ENV.APP.LOG_ACTIVE_GENERATION = false;
|
||||
ENV.APP.LOG_VIEW_LOOKUPS = false;
|
||||
|
||||
ENV.APP.rootElement = '#ember-testing';
|
||||
}
|
||||
|
||||
if (environment === 'production') {
|
||||
|
||||
}
|
||||
|
||||
return ENV;
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
/* global require, module */
|
||||
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
|
||||
|
||||
module.exports = function(defaults) {
|
||||
var app = new EmberApp(defaults, {
|
||||
// Add options here
|
||||
});
|
||||
|
||||
// Use `app.import` to add additional libraries to the generated
|
||||
// output files.
|
||||
//
|
||||
// If you need to use different assets in different
|
||||
// environments, specify an object as the first parameter. That
|
||||
// object's keys should be the environment name and the values
|
||||
// should be the asset to use in that environment.
|
||||
//
|
||||
// If the library that you are including contains AMD or ES6
|
||||
// modules that you would like to import into your application
|
||||
// please specify an object with the list of modules as keys
|
||||
// along with the exports of each module as its value.
|
||||
|
||||
return app.toTree();
|
||||
};
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "ember-hifi",
|
||||
"version": "0.0.0",
|
||||
"description": "Small description for ember-hifi goes here",
|
||||
"private": true,
|
||||
"directories": {
|
||||
"doc": "doc",
|
||||
"test": "tests"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "ember server",
|
||||
"build": "ember build",
|
||||
"test": "ember test"
|
||||
},
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"broccoli-asset-rev": "^2.0.2",
|
||||
"ember-browserify": "^1.0.1",
|
||||
"ember-cli": "1.13.1",
|
||||
"ember-cli-app-version": "0.4.0",
|
||||
"ember-cli-babel": "^5.0.0",
|
||||
"ember-cli-content-security-policy": "0.4.0",
|
||||
"ember-cli-dependency-checker": "^1.0.0",
|
||||
"ember-cli-font-awesome": "0.1.0",
|
||||
"ember-cli-htmlbars": "0.7.9",
|
||||
"ember-cli-htmlbars-inline-precompile": "^0.1.1",
|
||||
"ember-cli-ic-ajax": "0.2.1",
|
||||
"ember-cli-inject-live-reload": "^1.3.0",
|
||||
"ember-cli-qunit": "0.3.15",
|
||||
"ember-cli-release": "0.2.3",
|
||||
"ember-cli-uglify": "^1.0.1",
|
||||
"ember-data": "1.13.5",
|
||||
"ember-disable-proxy-controllers": "^1.0.0",
|
||||
"ember-export-application-global": "^1.0.2",
|
||||
"ember-localstorage-adapter": "0.5.4"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
|
||||
<cross-domain-policy>
|
||||
<!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
|
||||
|
||||
<!-- Most restrictive policy: -->
|
||||
<site-control permitted-cross-domain-policies="none"/>
|
||||
|
||||
<!-- Least restrictive policy: -->
|
||||
<!--
|
||||
<site-control permitted-cross-domain-policies="all"/>
|
||||
<allow-access-from domain="*" to-ports="*" secure="false"/>
|
||||
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
|
||||
-->
|
||||
</cross-domain-policy>
|
После Ширина: | Высота: | Размер: 16 KiB |
После Ширина: | Высота: | Размер: 16 KiB |
После Ширина: | Высота: | Размер: 37 KiB |
После Ширина: | Высота: | Размер: 3.2 KiB |
После Ширина: | Высота: | Размер: 88 KiB |
После Ширина: | Высота: | Размер: 6.6 KiB |
После Ширина: | Высота: | Размер: 7.1 KiB |
После Ширина: | Высота: | Размер: 11 KiB |
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"version": "@@versionNumber",
|
||||
"name": "@@appName",
|
||||
"description": "@@appDescription",
|
||||
"icons": {
|
||||
"32": "/assets/images/icons/icon-32.png",
|
||||
"60": "/assets/images/icons/icon-60.png",
|
||||
"64": "/assets/images/icons/icon-64.png",
|
||||
"90": "/assets/images/icons/icon-90.png",
|
||||
"120": "/assets/images/icons/icon-120.png",
|
||||
"128": "/assets/images/icons/icon-128.png",
|
||||
"256": "/assets/images/icons/icon-256.png",
|
||||
"512": "/assets/images/icons/icon-512.png"
|
||||
},
|
||||
"developer": {
|
||||
"name": "@@developerName",
|
||||
"url": "@@developerUrl"
|
||||
},
|
||||
"launch_path": "/index.html",
|
||||
"installs_allowed_from": ["https://marketplace.firefox.com", "*"],
|
||||
"permissions": {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# http://www.robotstxt.org
|
||||
User-agent: *
|
||||
Disallow:
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"framework": "qunit",
|
||||
"test_page": "tests/index.html?hidepassed",
|
||||
"disable_watching": true,
|
||||
"launch_in_ci": [
|
||||
"PhantomJS"
|
||||
],
|
||||
"launch_in_dev": [
|
||||
"PhantomJS",
|
||||
"Chrome"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"predef": [
|
||||
"document",
|
||||
"window",
|
||||
"location",
|
||||
"setTimeout",
|
||||
"$",
|
||||
"-Promise",
|
||||
"define",
|
||||
"console",
|
||||
"visit",
|
||||
"exists",
|
||||
"fillIn",
|
||||
"click",
|
||||
"keyEvent",
|
||||
"triggerEvent",
|
||||
"find",
|
||||
"findWithAssert",
|
||||
"wait",
|
||||
"DS",
|
||||
"andThen",
|
||||
"currentURL",
|
||||
"currentPath",
|
||||
"currentRouteName"
|
||||
],
|
||||
"node": false,
|
||||
"browser": false,
|
||||
"boss": true,
|
||||
"curly": true,
|
||||
"debug": false,
|
||||
"devel": false,
|
||||
"eqeqeq": true,
|
||||
"evil": true,
|
||||
"forin": false,
|
||||
"immed": false,
|
||||
"laxbreak": false,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": false,
|
||||
"nonew": false,
|
||||
"nomen": false,
|
||||
"onevar": false,
|
||||
"plusplus": false,
|
||||
"regexp": false,
|
||||
"undef": true,
|
||||
"sub": true,
|
||||
"strict": false,
|
||||
"white": false,
|
||||
"eqnull": true,
|
||||
"esnext": true,
|
||||
"unused": true
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import Resolver from 'ember/resolver';
|
||||
import config from '../../config/environment';
|
||||
|
||||
var resolver = Resolver.create();
|
||||
|
||||
resolver.namespace = {
|
||||
modulePrefix: config.modulePrefix,
|
||||
podModulePrefix: config.podModulePrefix
|
||||
};
|
||||
|
||||
export default resolver;
|
|
@ -0,0 +1,18 @@
|
|||
import Ember from 'ember';
|
||||
import Application from '../../app';
|
||||
import config from '../../config/environment';
|
||||
|
||||
export default function startApp(attrs) {
|
||||
var application;
|
||||
|
||||
var attributes = Ember.merge({}, config.APP);
|
||||
attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
|
||||
|
||||
Ember.run(function() {
|
||||
application = Application.create(attributes);
|
||||
application.setupForTesting();
|
||||
application.injectTestHelpers();
|
||||
});
|
||||
|
||||
return application;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>EmberHifi Tests</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
{{content-for 'head'}}
|
||||
{{content-for 'test-head'}}
|
||||
|
||||
<link rel="stylesheet" href="assets/vendor.css">
|
||||
<link rel="stylesheet" href="assets/ember-hifi.css">
|
||||
<link rel="stylesheet" href="assets/test-support.css">
|
||||
|
||||
{{content-for 'head-footer'}}
|
||||
{{content-for 'test-head-footer'}}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{{content-for 'body'}}
|
||||
{{content-for 'test-body'}}
|
||||
<script src="assets/vendor.js"></script>
|
||||
<script src="assets/test-support.js"></script>
|
||||
<script src="assets/ember-hifi.js"></script>
|
||||
<script src="testem.js"></script>
|
||||
<script src="assets/test-loader.js"></script>
|
||||
|
||||
{{content-for 'body-footer'}}
|
||||
{{content-for 'test-body-footer'}}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
import resolver from './helpers/resolver';
|
||||
import {
|
||||
setResolver
|
||||
} from 'ember-qunit';
|
||||
|
||||
setResolver(resolver);
|
|
@ -0,0 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('adapter:application', 'Unit | Adapter | application', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['serializer:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
var adapter = this.subject();
|
||||
assert.ok(adapter);
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
|
||||
moduleForComponent('audio-player', 'Unit | Component | audio player', {
|
||||
// Specify the other units that are required for this test
|
||||
// needs: ['component:foo', 'helper:bar'],
|
||||
unit: true
|
||||
});
|
||||
|
||||
test('it renders', function(assert) {
|
||||
assert.expect(2);
|
||||
|
||||
// Creates the component instance
|
||||
var component = this.subject();
|
||||
assert.equal(component._state, 'preRender');
|
||||
|
||||
// Renders the component to the page
|
||||
this.render();
|
||||
assert.equal(component._state, 'inDOM');
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:application', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
var controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:episodes', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
var controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:player', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
var controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:podcast', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
var controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('controller:podcasts', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
var controller = this.subject();
|
||||
assert.ok(controller);
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
import { t } from '../../../helpers/t';
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
module('Unit | Helper | t');
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it works', function(assert) {
|
||||
var result = t(42);
|
||||
assert.ok(result);
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
import { moduleForModel, test } from 'ember-qunit';
|
||||
|
||||
moduleForModel('episode', 'Unit | Model | episode', {
|
||||
// Specify the other units that are required for this test.
|
||||
needs: []
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
var model = this.subject();
|
||||
// var store = this.store();
|
||||
assert.ok(!!model);
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
import { moduleForModel, test } from 'ember-qunit';
|
||||
|
||||
moduleForModel('podcast', 'Unit | Model | podcast', {
|
||||
// Specify the other units that are required for this test.
|
||||
needs: []
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
var model = this.subject();
|
||||
// var store = this.store();
|
||||
assert.ok(!!model);
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:application', 'Unit | Route | application', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
var route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:podcast', 'Unit | Route | podcast', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
var route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:podcasts', 'Unit | Route | podcasts', {
|
||||
// Specify the other units that are required for this test.
|
||||
// needs: ['controller:foo']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
var route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
import { moduleForModel, test } from 'ember-qunit';
|
||||
|
||||
moduleForModel('application', 'Unit | Serializer | application', {
|
||||
// Specify the other units that are required for this test.
|
||||
needs: ['serializer:application']
|
||||
});
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it serializes records', function(assert) {
|
||||
var record = this.subject();
|
||||
|
||||
var serializedRecord = record.serialize();
|
||||
|
||||
assert.ok(serializedRecord);
|
||||
});
|