bunch of cleanup, reorganization, and get alarm/wakeup to work

This commit is contained in:
Colin Frei 2013-07-09 21:42:24 +02:00
parent 6d133cfd72
commit f8258c7a7e
13 changed files with 501 additions and 269 deletions

View file

@ -13,8 +13,7 @@ body, .normalFont {
.main-container {
height: 100%;
height: -webkit-calc(100% - 30px);
height: calc(100% - 30px);
height: calc(100% - 42px);
}
@ -31,12 +30,16 @@ body, .normalFont {
.topBar .topBarItem {
padding: 6px;
text-align: center;
height: 18px;
height: 30px;
font-size: 14px;
}
.topBar a, .topBar a:visited {
text-decoration: none;
color: white;
}
.topBar .topBarButton {
font-size: 24px;
}
#controlButton {
width: 50px;
@ -59,27 +62,26 @@ body, .normalFont {
.pageswitch-icon {
transition-property: font-size, top, left, color;
-webkit-transition-property: font-size, top, left, color;
transition-duration: 1s;
-webkit-transition-duration: 1s;
position: absolute;
}
.pageswitch-icon.next {
font-size: 18px;
font-size: 30px;
top: 5px;
left: 20px;
left: 16px;
z-index: 10;
}
.pageswitch-icon.next1 {
font-size: 12px;
font-size: 20px;
top: 12px;
left: 33px;
left: 40px;
z-index: 8;
color: #708090;
}
.pageswitch-icon.next2 {
font-size: 10px;
font-size: 18px;
top: 3px;
left: 33px;
left: 40px;
z-index: 6;
color: #708090;
}
@ -124,7 +126,6 @@ body, .normalFont {
.fullCurrentInfo {
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 10px;
}
@ -171,6 +172,15 @@ body, .normalFont {
height: 100%;
}
.newFeedField {
width: calc(100% - 60px);
margin: 5px;
}
input {
height: 24px;
}
/* form */
form.importForm {
padding: 10px;
@ -182,7 +192,6 @@ form.importForm {
height: 25px;
margin: 5px 0;
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
}
.importForm input[type="submit"] {
@ -194,7 +203,6 @@ label {
.feedData_tmp {
display: inline-block;
width: 50%;
@ -203,3 +211,28 @@ label {
.feedImageThumbnail {
width:40px;
}
select {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 13px;
font-weight: normal;
display: inline-block;
width: 210px;
padding: 4px;
margin-bottom: 9px;
font-size: 13px;
color: #555555;
border: 1px solid #ccc;
-webkit-border-radius: 3px;
border-radius: 3px;
height: 28px;
/* In IE7, the height of the select element cannot be changed by height, only font-size */
margin-top: 4px;
/* For IE7, add top margin to align select with labels */
line-height: 28px;
}
.active {
color: red;
}

View file

@ -17,9 +17,9 @@
<i id="pageswitch-icon-queue" class="pageswitch-icon next2 icon-th-list"></i>
<i id="pageswitch-icon-info" class="pageswitch-icon icon-info-sign" ng-show="showInfoIcon"></i>
</div>
<div id="controlButton" class="topBarItem" ng-click="playPause()">
<i class="icon-play"></i>
<i class="icon-pause"></i>
<div id="controlButton" class="topBarItem topBarButton" ng-click="playPause()">
<i class="icon-play" ng-class=""></i>
<i class="icon-pause" ng-class=""></i>
</div>
<div ng-click="currentInfo()" class="topBarItem">
<span>{{ nowPlaying.title }}</span>
@ -30,7 +30,6 @@
<div class="fullCurrentInfo topBarMenu" ng-show="showingFullCurrentInfo" ng-cloak>
{{ nowPlaying.description }}
{{ nowPlaying.date|date }}
more information about song playing (description, link to go to this feed, more controls?)
</div>
<div class="pageSwitchMenu topBarMenu" ng-show="showingPageSwitchMenu" ng-cloak>
<ul>
@ -48,6 +47,7 @@
<script src="lib/angular/angular.js"></script>
<script src="lib/iscroll.js"></script>
<script src="js/alarmManagers.js"></script>
<script src="js/app.js"></script>
<script src="js/utilities.js"></script>
<script src="js/services.js"></script>

107
js/alarmManagers.js Normal file
View file

@ -0,0 +1,107 @@
'use strict';
angular.module('podcasts.alarmManager', ['podcasts.settings', 'podcasts.downloader'])
.run(['alarmManager', 'updateFeedsAlarmManager', function(alarmManager, updateFeedsAlarmManager) {
updateFeedsAlarmManager.setAlarmListener();
alarmManager.setAlarmListener();
}])
.service('alarmManager', function() {
var alarmManager = navigator.mozAlarms,
alarmHandlers = [];
if (!alarmManager) {
console.log('navigator.mozAlarms is not available');
return {
setAlarmIn: angular.noop,
removeExistingAlarms: angular.noop,
setAlarmListener: angular.noop,
addAlarmListener: angular.noop
};
}
function setAlarmIn(milliSeconds, data) {
var now = new Date(),
alarmDate = new Date(+now + +milliSeconds);
//TODO: check how to set timezone-specific alarms
var setAlarmRequest = alarmManager.add(alarmDate, "ignoreTimezone", data);
setAlarmRequest.onsuccess = function () {
console.log("Alarm scheduled for " + alarmDate);
};
setAlarmRequest.onerror = function () {
console.log("An error occurred when scheduling the alarm: " + e.target.error.name);
};
}
function removeExistingAlarms(type)
{
var allAlarms = alarmManager.getAll();
allAlarms.onsuccess = function (e) {
this.result.forEach(function (alarm) {
if (type === alarm.data.type) {
alarmManager.remove(alarm.id);
}
});
};
}
function addAlarmListener(type, alarmFunction)
{
alarmHandlers.push({type: type, handle: alarmFunction});
}
function handleAlarm(alarm)
{
alarmHandlers.forEach(function (alarmHandler) {
if (alarm.data.type == alarmHandler.type) {
alarmHandler.handle(alarm);
}
});
}
function setAlarmListener()
{
navigator.mozSetMessageHandler("alarm", handleAlarm);
}
return {
setAlarmIn: setAlarmIn,
removeExistingAlarms: removeExistingAlarms,
addAlarmListener: addAlarmListener,
setAlarmListener: setAlarmListener
};
})
.service('updateFeedsAlarmManager', ['settings', 'alarmManager', 'downloader', function(settings, alarmManager, downloader) {
var alarmType = "updateFeeds";
function setAlarm()
{
settings.get('refreshInterval', function(value) {
if (value.value > 0) {
var refreshInterval = value.value;
alarmManager.setAlarmIn(refreshInterval, {type: alarmType});
}
});
}
function changeAlarmInterval(newInterval)
{
alarmManager.removeExistingAlarms(alarmType);
this.setAlarm();
}
function setAlarmListener()
{
alarmManager.addAlarmListener(alarmType, function(alarm) {
downloader.downloadAll(true);
setAlarm();
});
}
return {
setAlarm: setAlarm,
changeAlarmInterval: changeAlarmInterval,
setAlarmListener: setAlarmListener
};
}]);

View file

@ -9,5 +9,6 @@ angular.module('podcasts', ['podcasts.services', 'podcasts.updater', 'podcasts.d
$routeProvider.when('/settings', {templateUrl: 'partials/settings.html', controller: SettingsCtrl});
$routeProvider.when('/import/google', {templateUrl: 'partials/importGoogle.html', controller: ImportCtrl});
$routeProvider.when('/info', {templateUrl: 'partials/info.html', controller: InfoCtrl});
$routeProvider.when('/dev', {templateUrl: 'partials/dev.html', controller: DevCtrl});
$routeProvider.otherwise({redirectTo: '/queue'});
}]);

View file

@ -9,6 +9,18 @@ function FeedListCtrl($scope, feeds, pageSwitcher, $location) {
feeds.add($scope.newFeedUrl);
};
$scope.preFillField = function() {
if (angular.isUndefined($scope.newFeedUrl) || $scope.newFeedUrl == "") {
$scope.newFeedUrl = "http://";
}
};
$scope.removePrefillIfNecessary = function() {
if ($scope.newFeedUrl == "http://") {
$scope.newFeedUrl = "";
}
};
$scope.goToFeed = function(hash) {
$location.path('/feed/'+hash);
};
@ -16,47 +28,6 @@ function FeedListCtrl($scope, feeds, pageSwitcher, $location) {
pageSwitcher.change('feeds');
}
function TopLinksCtrl($scope, downloader, google) {
$scope.downloadFiles = function() {
downloader.downloadAll();
};
$scope.loadFixtures = function() {
var newFeed = {};
newFeed.title = "Some OGG Vorbis Podcast";
newFeed.url = "http://www.c3d2.de/pentacast-ogg.xml";
//add new record to the local database
ixDbEz.put("feed", newFeed);
var newFeedItem = {};
newFeedItem.guid = 'http://example.com/1';
newFeedItem.feedId = 1;
newFeedItem.title = 'Example Item 1';
newFeedItem.link = 'http://example.com/1';
newFeedItem.date = 'Date';
newFeedItem.description = 'Long Description<br /> with HTML <b>and stuff</b>';
newFeedItem.audioUrl = 'http://example.com/1';
newFeedItem.queued = 1;
ixDbEz.put("feedItem", newFeedItem);
var newFeedItem = {};
newFeedItem.guid = 'http://example.com/2';
newFeedItem.feedId = 1;
newFeedItem.title = 'Example Item 2';
newFeedItem.link = 'http://example.com/2';
newFeedItem.date = 'Date';
newFeedItem.description = 'Second Long Description<br /> with HTML <b>and stuff</b>';
newFeedItem.audioUrl = 'http://example.com/2';
newFeedItem.queued = 1;
ixDbEz.put("feedItem", newFeedItem);
};
}
function FeedCtrl($scope, $routeParams, $location, feeds, pageSwitcher) {
$scope.nrQueueItemsOptions = [1, 2, 3, 4, 5];
$scope.feed = {};
@ -101,7 +72,7 @@ function QueueListCtrl($scope, $rootScope, pageSwitcher, feedItems, feeds, queue
pageSwitcher.change('queue');
}
function SettingsCtrl($scope, settings, pageSwitcher) {
function SettingsCtrl($scope, settings, pageSwitcher, updateFeedsAlarmManager) {
$scope.refreshIntervalOptions = [
{name: '10 seconds', value: '10000'},
{name: '1 hour', value: '3600000'},
@ -112,11 +83,17 @@ function SettingsCtrl($scope, settings, pageSwitcher) {
$scope.settings = {};
$scope.changeInterval = function() {
settings.set('refreshInterval', $scope.refreshInterval.value, $scope.refreshInterval.id);
settings.set(
'refreshInterval',
$scope.settings.refreshInterval.value,
$scope.settings.refreshInterval.id
);
updateFeedsAlarmManager.changeAlarmInterval();
};
$scope.changeDownloadOnWifi = function() {
settings.set('downloadOnWifi', $scope.downloadOnWifi.value, $scope.downloadOnWifi.id);
settings.set('downloadOnWifi', $scope.settings.downloadOnWifi.value, $scope.settings.downloadOnWifi.id);
};
settings.setAllValuesInScope($scope);
@ -131,6 +108,7 @@ function TopBarCtrl($scope, player, pageSwitcher)
$scope.showingPageSwitchMenu = false;
$scope.showingFullCurrentInfo = false;
$scope.showInfoIcon = false;
$scope.playing = player.playing;
$scope.playPause = function() {
if (player.playing()) {
@ -182,4 +160,21 @@ function ImportCtrl($scope, pageSwitcher, google)
pageSwitcher.backPage = true;
pageSwitcher.change('settings');
}
function DevCtrl($scope, downloader, updateFeedsAlarmManager)
{
$scope.downloadFiles = function() {
downloader.downloadAll();
};
$scope.checkForPendingMessage = function() {
console.log(navigator.mozHasPendingMessage('alarm'));
};
$scope.setAlarmTmp = function() {
updateFeedsAlarmManager.setAlarm();
};
}

View file

@ -123,4 +123,24 @@ angular.module('podcast.directives', [])
}
};
})
.directive('ngFocus', ['$parse', function($parse) {
return function(scope, element, attr) {
var fn = $parse(attr['ngFocus']);
element.bind('focus', function(event) {
scope.$apply(function() {
fn(scope, {$event:event});
});
});
}
}])
.directive('ngBlur', ['$parse', function($parse) {
return function(scope, element, attr) {
var fn = $parse(attr['ngBlur']);
element.bind('blur', function(event) {
scope.$apply(function() {
fn(scope, {$event:event});
});
});
}
}])
;

View file

@ -2,38 +2,6 @@
/* Services */
angular.module('podcasts.services', ['podcasts.utilities'])
.service('downloaderBackend', ['$http', '$q', 'xmlParser', '$rootScope', function($http, $q, xmlParser, $rootScope) {
return {
downloadFile: function(url) {
var deferred = $q.defer();
$http.get(url, {'responseType': 'blob'})
.success(function(file) {
deferred.resolve(file);
})
.error(function() {
deferred.reject();
})
;
return deferred.promise;
},
downloadXml: function(url) {
var deferred = $q.defer();
$rootScope.$apply($http.get(url)
.success(function(xml) {
deferred.resolve(xmlParser.parse(xml));
})
.error(function(data, status, headers, config) {
deferred.reject();
})
);
return deferred.promise;
}
}
}])
.value('queueList', {
queue: [],
scope: null,
@ -130,7 +98,10 @@ angular.module('podcasts.services', ['podcasts.utilities'])
ixDbCursorReq.onsuccess = function (e) {
var cursor = ixDbCursorReq.result || e.result;
if (cursor) {
queueList.addToQueue(cursor.value);
// This additional check is necessary, since the index doesn't seem to always catch correctly
if (cursor.value.queued) {
queueList.addToQueue(cursor.value);
}
cursor.continue();
} else {
@ -140,7 +111,7 @@ angular.module('podcasts.services', ['podcasts.utilities'])
}
}
}
}, undefined, IDBKeyRange.only(1), undefined, 'ixQueued');
}, undefined, IDBKeyRange.only(1), false, 'ixQueued');
}
}
}])
@ -284,6 +255,7 @@ angular.module('podcasts.services', ['podcasts.utilities'])
downloadItems: function(feedItem, updateStatus) {
var promise = downloaderBackend.downloadXml(feedItem.url),
feedObjects = [];
promise.then(function(data) {
angular.forEach(
data.find('item'),
@ -324,86 +296,117 @@ angular.module('podcasts.services', ['podcasts.utilities'])
return {
url: $window.URL || $window.webkitURL,
createObjectUrl: function(data) {
return this.url.createObjectUrl(data);
return this.url.createObjectURL(data);
}
};
}])
.service('player', ['db', 'url', '$timeout', function(db, url, $timeout) {
var audioSetup = new Audio();
audioSetup.setAttribute("mozaudiochannel", "content");
var audio = new Audio();
audio.setAttribute("mozaudiochannel", "content");
var currentFeedItem = null;
var nowPlaying = {position: 0, duration: 0, title: '', description: '', feed: '', date: 0};
var acm = navigator.mozAudioChannelManager;
if (acm) {
acm.addEventListener('headphoneschange', function onheadphoneschange() {
if (!acm.headphones && PlayerView.isPlaying) {
PlayerView.pause();
}
});
}
function play(feedItem, $scope)
{
if (feedItem) {
currentFeedItem = feedItem;
var audioSrc;
if (feedItem.audio) {
console.log('Playing audio from download');
audioSrc = url.createObjectUrl(feedItem.audio);
} else {
console.log('Playing audio from web');
audioSrc = feedItem.audioUrl;
}
audio.src = audioSrc;
updateSong(feedItem, $scope);
if (feedItem.position) {
angular.element(audio).bind('canplay', function(event) {
this.currentTime = feedItem.position;
angular.element(this).unbind('canplay');
});
}
}
audio.play();
//TODO: handle save when feedItem is not passed in
angular.element(audio).bind('pause', function(event) {
feedItem.position = Math.floor(event.target.currentTime);
db.put("feedItem", feedItem);
angular.element(this).unbind();
});
// TODO: add something here for when audio is done to remove from queue and go to next song
angular.element(audio).bind('ended', function(event) {
feedItem.queued = 0;
feedItem.position = 0;
db.put("feedItem", feedItem);
// start next item
// get next item from queue
play(nextFeedItem, $scope);
angular.element(this).unbind();
});
}
function pause()
{
audio.pause();
}
function playing()
{
return !audio.paused;
}
function updateSong(feedItem, $scope)
{
nowPlaying.title = feedItem.title;
/*$timeout(function() {
player.nowPlaying.duration = audio.duration;
}, 100);*/
nowPlaying.currentFeedItem = feedItem;
nowPlaying.description = feedItem.description;
nowPlaying.feed = feedItem.feed;
nowPlaying.date = feedItem.date;
updatePosition($scope);
}
function updatePosition($scope)
{
setInterval(function() {
nowPlaying.position = audio.currentTime;
$scope.$apply();
}, 1000);
}
return {
db: db,
audio: audioSetup,
feedItem: null,
nowPlaying: {position: 0, duration: 0, title: '', description: '', feed: '', date: 0},
play: function (feedItem, $scope) {
if (feedItem) {
this.feedItem = feedItem;
var audioSrc;
if (feedItem.audio) {
audioSrc = url.createObjectUrl(feedItem.audio);
} else {
audioSrc = feedItem.audioUrl;
}
this.audio.src = audioSrc;
this.updateSong(feedItem, $scope);
if (feedItem.position) {
angular.element(this.audio).bind('canplay', function(event) {
this.currentTime = feedItem.position;
});
}
}
this.audio.play();
var db = this.db;
angular.element(this.audio).bind('pause', function(event) {
feedItem.position = Math.floor(event.target.currentTime);
db.put("feedItem", feedItem);
});
// TODO: add something here for when audio is done to remove from queue and go to next song
angular.element(this.audio).bind('ended', function(event) {
feedItem.queued = 0;
feedItem.position = 0;
db.put("feedItem", feedItem);
// start next item
// get next item from queue
play(nextFeedItem, $scope);
});
},
pause: function() {
this.audio.pause();
},
playing: function() {
return !this.audio.paused;
},
updateSong: function(feedItem, $scope) {
this.nowPlaying.title = feedItem.title;
var audio = this.audio,
player = this;
$timeout(function() {
player.nowPlaying.duration = audio.duration;
}, 100);
this.nowPlaying.feedItem = feedItem;
this.nowPlaying.description = feedItem.description;
this.nowPlaying.feed = feedItem.feed;
this.nowPlaying.date = feedItem.date;
this.updatePosition($scope);
},
updatePosition: function($scope) {
var audio = this.audio,
player = this;
setInterval(function() {
player.nowPlaying.position = audio.currentTime;
$scope.$apply();
}, 1000);
}
audio: audio,
feedItem: currentFeedItem,
nowPlaying: nowPlaying,
play: play,
pause: pause,
playing: playing,
updateSong: updateSong,
updatePosition: updatePosition
}
}])
.service('pageSwitcher', ['$location', '$route', function($location, $route) {
@ -471,77 +474,6 @@ angular.module('podcasts.services', ['podcasts.utilities'])
}
}
}])
.service('downloader', ['db', 'url', '$http', 'settings', function(db, url, $http, settings) {
return {
allowedToDownload: function(callback) {
settings.get('downloadOnWifi', function(setting) {
if (setting.value) {
//TODO: check if we're on wifi
callback(false);
} else {
callback(true);
}
}, function() {
callback(true); // Default value is "allowed" - maybe change this?
});
},
downloadAll: function(silent) {
var downloader = this;
this.allowedToDownload(function(value) {
if (!value) {
if (typeof silent !== 'undefined' && !silent) {
alert('not Downloading because not on WiFi'); //TODO: nicer error message?
}
} else {
var itemsToDownload = [];
db.getCursor("feedItem", function(ixDbCursorReq)
{
if(typeof ixDbCursorReq !== "undefined") {
ixDbCursorReq.onsuccess = function (e) {
var cursor = ixDbCursorReq.result || e.result;
if (cursor) {
if (!cursor.value.audio && cursor.value.audioUrl) {
itemsToDownload.push(cursor.value);
}
cursor.continue();
} else {
downloader.downloadFiles(itemsToDownload);
}
}
}
}, undefined, IDBKeyRange.only(1), undefined, 'ixQueued');
}
});
},
downloadFiles: function(itemsToDownload) {
var item = itemsToDownload.shift(),
downloader = this;
if (!item) {
return;
}
$http.get(item.audioUrl, {'responseType': 'blob'})
.success(function(data) {
item.audio = data;
item.duration = this.getAudioLength(data);
db.put("feedItem", item);
downloader.downloadFiles(itemsToDownload);
})
;
},
getAudioLength: function(audio) {
var tmpAudio = new Audio();
tmpAudio.autoplay = false;
tmpAudio.muted = true;
tmpAudio.src = url.createObjectURL(audio);
return tmpAudio.duration;
}
};
}])
.filter('time', function() {
return function(input, skip) {
var seconds, minutes, hours;
@ -592,7 +524,124 @@ angular.module('podcasts.services', ['podcasts.utilities'])
day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago" ||
"older than a month";
}
});
})
.service('downloaderBackend', ['$http', '$q', 'xmlParser', '$rootScope', function($http, $q, xmlParser, $rootScope) {
return {
downloadFile: function(url) {
var deferred = $q.defer();
$http.get(url, {'responseType': 'blob'})
.success(function(file) {
deferred.resolve(file);
})
.error(function() {
deferred.reject();
})
;
return deferred.promise;
},
downloadXml: function(url) {
var deferred = $q.defer();
$rootScope.$apply($http.get(url)
.success(function(xml) {
deferred.resolve(xmlParser.parse(xml));
})
.error(function(data, status, headers, config) {
deferred.reject();
})
);
return deferred.promise;
}
}
}]);
angular.module('podcasts.downloader', ['podcasts.settings', 'podcasts.database', 'podcasts.utilities'])
.service('downloader', ['db', 'url', '$http', 'settings', '$rootScope', function(db, url, $http, settings, $rootScope) {
return {
allowedToDownload: function(callback) {
callback(true);
/*
Not sure how to check this...
settings.get('downloadOnWifi', function(setting) {
if (setting.value) {
//TODO: check if we're on wifi
callback(false);
} else {
callback(true);
}
}, function() {
callback(true); // Default value is "allowed" - maybe change this?
});
*/
},
downloadAll: function(silent) {
var downloader = this;
this.allowedToDownload(function(value) {
if (!value) {
console.log('Not Allowed to Download because not on Wifi');
if (!angular.isUndefined(silent) && !silent) {
alert('not Downloading because not on WiFi'); //TODO: nicer error message?
}
} else {
var itemsToDownload = [];
db.getCursor("feedItem", function(ixDbCursorReq)
{
if(typeof ixDbCursorReq !== "undefined") {
ixDbCursorReq.onsuccess = function (e) {
var cursor = ixDbCursorReq.result || e.result;
if (cursor) {
if (!cursor.value.audio && cursor.value.audioUrl) {
itemsToDownload.push(cursor.value);
}
cursor.continue();
} else {
downloader.downloadFiles(itemsToDownload);
}
}
}
}, undefined, IDBKeyRange.only(1), undefined, 'ixQueued');
}
});
},
downloadFiles: function(itemsToDownload) {
var item = itemsToDownload.shift(),
downloader = this;
if (!item) {
return;
}
$rootScope.$apply(
$http.get(item.audioUrl, {'responseType': 'blob'})
.success(function(data) {
console.log('downloaded audio file for saving');
item.audio = data;
item.duration = downloader.getAudioLength(data);
db.put("feedItem", item);
downloader.downloadFiles(itemsToDownload);
})
.error(function() {
console.warn('Could not download file');
})
);
},
getAudioLength: function(audio) {
var tmpAudio = new Audio();
tmpAudio.autoplay = false;
tmpAudio.muted = true;
tmpAudio.src = url.createObjectUrl(audio);
return tmpAudio.duration;
}
};
}]);
angular.module('podcasts.database', [])
.run(function() {
@ -606,10 +655,11 @@ angular.module('podcasts.database', [])
ixDbEz.createIndex("feedItem", "ixQueued", "queued");
ixDbEz.createObjStore("setting", "id", true);
ixDbEz.createIndex("setting", "ixName", "name", true);
ixDbEz.put("setting", {'name': "refreshInterval", 'value': 20000});
});
//Create or Open the local IndexedDB database via ixDbEz
ixDbEz.startDB("podcastDb", 8, dbConfig, undefined, undefined, false);
ixDbEz.startDB("podcastDb", 10, dbConfig, undefined, undefined, false);
})
.value('db', ixDbEz)
.service('dbNew', ['$q', '$rootScope', 'db', function($q, $rootScope, _db) {
@ -645,25 +695,17 @@ angular.module('podcasts.database', [])
};
}]);
angular.module('podcasts.updater', ['podcasts.settings'])
angular.module('podcasts.updater', ['podcasts.settings', 'podcasts.alarmManager', 'podcasts.downloader'])
.run(['update', function(update) {
update.checkFeeds();
//update.checkFeeds();
}])
.service('update', ['$timeout', '$log', 'settings', 'downloader', function($timeout, $log, settings, downloader) {
.service('update', ['$log', 'downloader', 'updateFeedsAlarmManager', function($log, downloader, updateFeedsAlarmManager) {
var checkFeeds = function() {
$log.info('Running Feed Check');
settings.get('refreshInterval', function(value) {
if (value.value > 0) {
var refreshInterval = value.value;
update();
if (refreshInterval > 0) {
$timeout(checkFeeds, refreshInterval);
}
}
});
update();
updateFeedsAlarmManager.setAlarm();
};
function update() {
@ -687,7 +729,6 @@ angular.module('podcasts.settings', ['podcasts.database'])
waiting = [];
function _init() {
console.log('init settings');
db.getCursor("setting", function(ixDbCursorReq)
{
if(typeof ixDbCursorReq !== "undefined") {
@ -793,6 +834,13 @@ angular.module('podcasts.settings', ['podcasts.database'])
;
angular.module('podcasts.importer', [])
.service('opml', function() {
return {
import: function(url) {
}
}
})
.service('google', ['$q', '$http', 'feeds', function($q, $http, feeds) {
return {
import: function(email, password) {

View file

@ -14,4 +14,12 @@ angular.module('podcasts.utilities', [])
}
}
})
.service('url', ['$window', function($window) {
return {
url: $window.URL || $window.webkitURL,
createObjectUrl: function(data) {
return this.url.createObjectURL(data);
}
};
}])
;

View file

@ -320,7 +320,7 @@ var ixDbEz = (function () {
// This is a workaround for the fact that chrome doesn't support blobs.
// from: https://code.google.com/p/chromium/issues/detail?id=108012#c42
//* when reading something that should be a blob, check if typeof value === "string"; if so, return new Blob([value], {type: 'application/octet-stream'}); otherwise return the value, which should be a Blob
console.log('Couldn\'t save the Blob, trying a workaround');
angular.forEach(value, function(data, index) {
if (Object.prototype.toString.call(data) === '[object Blob]') {
var reader = new FileReader();

View file

@ -1,6 +1,6 @@
{
"name": "Podcast",
"version": "0.2.0",
"version": "0.3.0",
"description": "Podcast Manager for Firefox OS",
"icons": {
"128": "/blaIcon128.png"
@ -14,8 +14,12 @@
"permissions": {
"storage": { "description": "Allow Podcast to store podcast information for offline use" },
"systemXHR": { "description": "Allow Podcast to download podcast information" },
"audio-channel-content": { "description": "Allow Podcast to play audio in the background" }
"audio-channel-content": { "description": "Allow Podcast to play audio in the background" },
"alarms": { "description": "Allow Podcast to update in the background" }
},
"installs_allowed_from": ["*"],
"default_locale": "en"
"default_locale": "en",
"messages": [
{ "alarm": "/index.html" }
]
}

17
partials/dev.html Normal file
View file

@ -0,0 +1,17 @@
<button ng-click="downloadFiles()">Download Files</button>
<button ng-click="setAlarmTmp()">Set Alarm in 10 Seconds</button>
<button ng-click="checkForPendingMessage()">Check for pending Messages</button>
List of ALarms
$scope.feeds
<table>
<thead>
<td>Type</td>
<td>Date</td>
<td>more?</td>
</thead>
<tr ng-repeat="alarm in alarms">
<td>alarm.</td>
</tr>
</table>

View file

@ -1,5 +1,5 @@
<form ng-submit="addFeed()">
Add Feed: <input type="text" ng-model="newFeedUrl" /> <input type="submit" value="Add" />
<input type="text" class="newFeedField" ng-model="newFeedUrl" placeholder="Add Feed" ng-blur="removePrefillIfNecessary()" ng-focus="preFillField()" /><input type="submit" value="Add" />
</form>
<div ng-repeat="feed in feeds | orderBy:'title'" class="listItem"><!-- had ng-click="goToFeed(feed.id)" -->

View file

@ -1,13 +1,12 @@
<label for="refreshInterval">Refresh Subscriptions:</label>
<select name="refreshInterval" ng-change="changeInterval()" setting ng-model="settings.refreshInterval.value" ng-options="i.value as i.name for i in refreshIntervalOptions">
</select>
<select name="refreshInterval" id="refreshInterval" ng-change="changeInterval()" ng-model="settings.refreshInterval.value" ng-options="option.value as option.name for option in refreshIntervalOptions"></select>
<br />
<!--
<label for="downloadOnWifi">Only Download on Wi-Fi</label>
<input name="downloadOnWifi" type="checkbox" ng-change="changeDownloadOnWifi()" setting ng-model="settings.downloadOnWifi.value" />
-->
<!-- Store X Items Offline -->
<div ng-controller="TopLinksCtrl">
<button ng-click="downloadFiles()">Download Files</button>
<button ng-click="loadFixtures()">Load Fixtures</button><br />
<a href="#/import/google">Import Feeds from Google</a>
</div>
<a href="#/dev">Developer Options</a>
<a href="#/info">About</a>