diff --git a/css/core.css b/css/core.css index db4b965..8f19950 100644 --- a/css/core.css +++ b/css/core.css @@ -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; +} \ No newline at end of file diff --git a/index.html b/index.html index 4f44a13..7b1f066 100644 --- a/index.html +++ b/index.html @@ -17,9 +17,9 @@ -
- - +
+ +
{{ nowPlaying.title }} @@ -30,7 +30,6 @@
{{ nowPlaying.description }} {{ nowPlaying.date|date }} - more information about song playing (description, link to go to this feed, more controls?)
    @@ -48,6 +47,7 @@ + diff --git a/js/alarmManagers.js b/js/alarmManagers.js new file mode 100644 index 0000000..2598e4d --- /dev/null +++ b/js/alarmManagers.js @@ -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 + }; + }]); diff --git a/js/app.js b/js/app.js index bab0dc3..8c33adc 100644 --- a/js/app.js +++ b/js/app.js @@ -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'}); }]); \ No newline at end of file diff --git a/js/controllers.js b/js/controllers.js index 598e08a..d032d07 100644 --- a/js/controllers.js +++ b/js/controllers.js @@ -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
    with HTML and stuff'; - 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
    with HTML and stuff'; - 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(); + }; } \ No newline at end of file diff --git a/js/directives.js b/js/directives.js index f7eb931..40d2d71 100644 --- a/js/directives.js +++ b/js/directives.js @@ -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}); + }); + }); + } + }]) ; \ No newline at end of file diff --git a/js/services.js b/js/services.js index ccfbea0..8903aad 100644 --- a/js/services.js +++ b/js/services.js @@ -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) { diff --git a/js/utilities.js b/js/utilities.js index 00a0f6f..8ba1989 100644 --- a/js/utilities.js +++ b/js/utilities.js @@ -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); + } + }; + }]) ; diff --git a/lib/ixDbEz.js b/lib/ixDbEz.js index 069042e..cc7e395 100644 --- a/lib/ixDbEz.js +++ b/lib/ixDbEz.js @@ -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(); diff --git a/manifest.webapp b/manifest.webapp index 3a2dda9..69ecb42 100644 --- a/manifest.webapp +++ b/manifest.webapp @@ -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" } + ] } \ No newline at end of file diff --git a/partials/dev.html b/partials/dev.html new file mode 100644 index 0000000..3a59152 --- /dev/null +++ b/partials/dev.html @@ -0,0 +1,17 @@ + + + + + +List of ALarms +$scope.feeds + + + + + + + + + +
    TypeDatemore?
    alarm.
    \ No newline at end of file diff --git a/partials/listFeeds.html b/partials/listFeeds.html index bb277ce..f87fd0f 100644 --- a/partials/listFeeds.html +++ b/partials/listFeeds.html @@ -1,5 +1,5 @@
    - Add Feed: +
    diff --git a/partials/settings.html b/partials/settings.html index 6ca6835..35c4bf4 100644 --- a/partials/settings.html +++ b/partials/settings.html @@ -1,13 +1,12 @@ - +
    + -
    - -
    - Import Feeds from Google -
    \ No newline at end of file +Developer Options + +About \ No newline at end of file