├── .gitignore ├── README.md ├── scripts ├── filter │ ├── hash.js │ └── rssDate.js ├── controller │ ├── FeedList.js │ ├── ItemsCrtl.js │ ├── ItemCrtl.js │ └── FeedManageCrtl.js ├── service │ ├── googleapis.feed.js │ ├── HashString.js │ ├── LocalObjectStorage.js │ └── FeedList.js └── app.js ├── views ├── item.html ├── manage │ ├── list.html │ └── add.html └── list.html ├── css └── app.css └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | AngularJSFeedReader 2 | =================== 3 | 4 | A simple AngularJS based rss feed reader using the google jsonsp feed api. 5 | -------------------------------------------------------------------------------- /scripts/filter/hash.js: -------------------------------------------------------------------------------- 1 | angular.module('caco.MiniRSS') 2 | .filter('hash', function (HashString) { 3 | return function (value) { 4 | return HashString.perform(value); 5 | }; 6 | }); -------------------------------------------------------------------------------- /scripts/filter/rssDate.js: -------------------------------------------------------------------------------- 1 | angular.module('caco.MiniRSS') 2 | .filter('rssDate', function () { 3 | return function (value) { 4 | return new Date(value).toLocaleString(); 5 | }; 6 | }); -------------------------------------------------------------------------------- /views/item.html: -------------------------------------------------------------------------------- 1 |

ok

2 |
3 |

{{feed.title}}

4 |

{{item.title}}

5 |

6 |
7 | -------------------------------------------------------------------------------- /scripts/controller/FeedList.js: -------------------------------------------------------------------------------- 1 | angular.module('caco.MiniRSS') 2 | .controller('FeedListCtrl', function ($scope, FeedList) { 3 | $scope.feeds = FeedList.get(); 4 | 5 | $scope.$on('FeedList', function (event, data) { 6 | $scope.feeds = data; 7 | }); 8 | }); -------------------------------------------------------------------------------- /scripts/controller/ItemsCrtl.js: -------------------------------------------------------------------------------- 1 | angular.module('caco.MiniRSS') 2 | .controller('ItemsCtrl', function ($scope, $routeParams, FeedList, FeedLoad) { 3 | var feed = FeedList.getById($routeParams.id || FeedList.getMinId()) 4 | 5 | FeedLoad.fetch({q: feed.url, num: 50}, {}, function (data) { 6 | $scope.feed = data.responseData.feed; 7 | $scope.feed.id = feed.id; 8 | }); 9 | }); -------------------------------------------------------------------------------- /css/app.css: -------------------------------------------------------------------------------- 1 | .fade-enter-setup{ 2 | -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 2.0s; 3 | -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 2.0s; 4 | -ms-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 2.0s; 5 | -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 2.0s; 6 | transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 2.0s; 7 | opacity: 0; 8 | } 9 | 10 | .fade-enter-start{ 11 | opacity: 1; 12 | } 13 | 14 | .navbar-fixed-top{ 15 | position: static; 16 | padding-bottom: 10px; 17 | } -------------------------------------------------------------------------------- /scripts/service/googleapis.feed.js: -------------------------------------------------------------------------------- 1 | angular.module('caco.MiniRSS.googleapis.feed', ['ngResource']) 2 | .factory('FeedLoad', function ($resource) { 3 | return $resource('http://ajax.googleapis.com/ajax/services/feed/load', {}, { 4 | fetch: { method: 'JSONP', params: {v: '1.0', callback: 'JSON_CALLBACK'} } 5 | }); 6 | }) 7 | .factory('UrlLookup', function ($resource) { 8 | return $resource('http://ajax.googleapis.com/ajax/services/feed/lookup', {}, { 9 | fetch: { method: 'JSONP', params: {v: '1.0', callback: 'JSON_CALLBACK'} } 10 | }); 11 | }); -------------------------------------------------------------------------------- /scripts/service/HashString.js: -------------------------------------------------------------------------------- 1 | //based on http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ 2 | angular.module('caco.MiniRSS') 3 | .service('HashString', function () { 4 | this.perform = function(str){ 5 | var hash = 0; 6 | if (str.length == 0) { 7 | return hash; 8 | } 9 | 10 | for (var i = str.length - 1; i >= 0; i--) { 11 | char = str.charCodeAt(i); 12 | hash = ((hash<<5)-hash)+char; 13 | hash = hash & hash; 14 | } 15 | 16 | return hash; 17 | }; 18 | }); -------------------------------------------------------------------------------- /scripts/service/LocalObjectStorage.js: -------------------------------------------------------------------------------- 1 | angular.module('caco.LocalObjectStorage', []) 2 | .service('LocalObjectStorage', function () { 3 | this.getObject = function (key) { 4 | return JSON.parse(localStorage.getItem(key)) 5 | }; 6 | 7 | this.setObject = function (key, value) { 8 | localStorage.setItem(key, JSON.stringify(value)); 9 | }; 10 | 11 | this.removeObject = function (key) { 12 | localStorage.removeItem(key); 13 | }; 14 | 15 | this.contains = function (key) { 16 | return localStorage.getItem(key) ? true : false; 17 | }; 18 | }); -------------------------------------------------------------------------------- /scripts/controller/ItemCrtl.js: -------------------------------------------------------------------------------- 1 | angular.module('caco.MiniRSS') 2 | .controller('ItemCrtl', function ($scope, $routeParams, FeedList, FeedLoad, HashString) { 3 | var feed = FeedList.getById($routeParams.id) 4 | 5 | FeedLoad.fetch({q: feed.url, num: 50}, {}, function (data) { 6 | $scope.feed = data.responseData.feed; 7 | $scope.id = $routeParams.id; 8 | var entries = data.responseData.feed.entries; 9 | 10 | for (var i = entries.length - 1; i >= 0; i--) { 11 | if (HashString.perform(entries[i].title) == $routeParams.hashKey) { 12 | $scope.item = entries[i]; 13 | } 14 | } 15 | }); 16 | }); -------------------------------------------------------------------------------- /scripts/app.js: -------------------------------------------------------------------------------- 1 | angular.module('caco.MiniRSS', ['caco.MiniRSS.FeedList', 'caco.MiniRSS.googleapis.feed', 'ngRoute', 'ngSanitize']) 2 | .config(function ($routeProvider) { 3 | $routeProvider 4 | .when('/', {templateUrl: 'views/list.html', controller: 'ItemsCtrl'}) 5 | .when('/feed/:id', {templateUrl: 'views/list.html', controller: 'ItemsCtrl'}) 6 | .when('/feed/:id/item/:hashKey',{templateUrl: 'views/item.html', controller: 'ItemCrtl'}) 7 | .when('/manage', {templateUrl: 'views/manage/list.html', controller: 'FeedManage'}) 8 | .when('/manage/add', {templateUrl: 'views/manage/add.html', controller: 'FeedManage'}) 9 | }); 10 | -------------------------------------------------------------------------------- /views/manage/list.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 13 | 20 | 21 | 22 |
10 | 11 | 12 | 14 |
15 | 16 | 17 | 18 |
19 |
23 | -------------------------------------------------------------------------------- /views/list.html: -------------------------------------------------------------------------------- 1 |
2 |

{{feed.title}}

3 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 24 | 27 | 28 | 29 |
8 |
9 | 11 |
12 |
18 | 19 | 20 | 21 |
22 | 23 |
25 | {{item.publishedDate | rssDate}} 26 |
30 |
31 | -------------------------------------------------------------------------------- /scripts/controller/FeedManageCrtl.js: -------------------------------------------------------------------------------- 1 | angular.module('caco.MiniRSS') 2 | .controller('FeedManage', function ($scope, $location, UrlLookup, FeedLoad, FeedList) { 3 | $scope.feeds = FeedList.get(); 4 | 5 | $scope.add = function () { 6 | FeedList.add($scope.feed.url, $scope.feed.title); 7 | $location.path('/manage'); 8 | }; 9 | 10 | $scope.lookup = function () { 11 | UrlLookup.fetch({q: $scope.lookup.url}, {}, function (data) { 12 | if (data.responseStatus != 200 || (data.responseData && data.responseData.url == '')) { 13 | alert(data.responseDetails || 'Feed not found!'); 14 | return; 15 | } 16 | 17 | $scope.feed = data.responseData; 18 | FeedLoad.fetch({q: data.responseData.url}, {}, function (data) { //lookup title 19 | if (data.responseStatus != 200) { 20 | return; 21 | } 22 | 23 | $scope.feed.title = data.responseData.feed.title; 24 | }); 25 | }); 26 | }; 27 | 28 | $scope.delete = function (id) { 29 | FeedList.delete(id); 30 | }; 31 | 32 | $scope.$on('FeedList', function (event, data) { 33 | $scope.feeds = data; 34 | }); 35 | }); -------------------------------------------------------------------------------- /scripts/service/FeedList.js: -------------------------------------------------------------------------------- 1 | angular.module('caco.MiniRSS.FeedList', ['caco.LocalObjectStorage']) 2 | .service('FeedList', function ($rootScope, LocalObjectStorage) { 3 | this.add = function (url, title) { 4 | var list = this.get(); 5 | var id = localStorage.getItem('FeedListId') ? localStorage.getItem('FeedListId') : 1; 6 | 7 | list.push({ 8 | url: url, 9 | title: title, 10 | id: id 11 | }); 12 | 13 | LocalObjectStorage.setObject('FeedList', list); 14 | localStorage.setItem('FeedListId', ++id); 15 | $rootScope.$broadcast('FeedList', list); 16 | }; 17 | 18 | this.delete = function (id) { 19 | var list = this.get(); 20 | 21 | for (var i = list.length - 1; i >= 0; i--) { 22 | if (list[i].id == id) { 23 | list.splice(i, 1); 24 | } 25 | } 26 | 27 | LocalObjectStorage.setObject('FeedList', list); 28 | $rootScope.$broadcast('FeedList', list); 29 | }; 30 | 31 | this.get = function () { 32 | if (LocalObjectStorage.contains('FeedList')) { 33 | return LocalObjectStorage.getObject('FeedList'); 34 | } 35 | 36 | return new Array({ 37 | url: 'http://cacodaemon.de/index.php?rss=1', 38 | title: 'Cacomania', 39 | id: 0 40 | }); 41 | }; 42 | 43 | this.getById = function(id) { 44 | var list = this.get(); 45 | 46 | for (var i = list.length - 1; i >= 0; i--) { 47 | if (list[i].id == id) { 48 | return list[i]; 49 | } 50 | } 51 | 52 | return null; 53 | }; 54 | 55 | this.getMinId = function () { 56 | var list = this.get(); 57 | var minId = Number.MAX_VALUE; 58 | 59 | for (var i = list.length - 1; i >= 0; i--) { 60 | minId = Math.min(minId, list[i].id); 61 | } 62 | 63 | return minId; 64 | }; 65 | }); -------------------------------------------------------------------------------- /views/manage/add.html: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
8 |
9 |
10 | Lookup a feed URL 11 |
12 | 13 | 14 |
15 | 17 |
18 |
19 |
20 | 21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Add a feed 29 | 30 |
31 | 32 | 33 |
34 | 36 |
37 |
38 | 39 |
40 | 41 | 42 |
43 | 45 |
46 |
47 |
48 | 49 |
50 |
51 |
52 |
53 |
-------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | caco[miniRSS] 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 25 | 26 |
27 |
28 |
29 | 37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | --------------------------------------------------------------------------------