forked from Archives/Athou_commafeed
removed wicket and tomee, use dropwizard instead. remove wro4j, use gulp instead
This commit is contained in:
1456
src/main/app/js/controllers.js
Normal file
1456
src/main/app/js/controllers.js
Normal file
File diff suppressed because it is too large
Load Diff
361
src/main/app/js/directives.js
Normal file
361
src/main/app/js/directives.js
Normal file
@@ -0,0 +1,361 @@
|
||||
var module = angular.module('commafeed.directives', []);
|
||||
|
||||
module.directive('focus', ['$timeout', function($timeout) {
|
||||
return {
|
||||
restrict : 'A',
|
||||
link : function(scope, element, attrs) {
|
||||
scope.$watch(attrs.focus, function(value) {
|
||||
if (!value)
|
||||
return;
|
||||
$timeout(function() {
|
||||
$(element).focus();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
module.directive('confirmClick', [function() {
|
||||
return {
|
||||
priority : -1,
|
||||
restrict : 'A',
|
||||
link : function(scope, element, attrs) {
|
||||
element.bind('click', function(e) {
|
||||
var message = attrs.confirmClick;
|
||||
if (message && !confirm(message)) {
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
/**
|
||||
* Open a popup window pointing to the url in the href attribute
|
||||
*/
|
||||
module.directive('popup', function() {
|
||||
var opts = 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=800';
|
||||
return {
|
||||
link : function(scope, elm, attrs) {
|
||||
elm.bind('click', function(event) {
|
||||
window.open(this.href, '', opts);
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* entry tag handling
|
||||
*/
|
||||
module.directive('tags', function() {
|
||||
return {
|
||||
restrict : 'E',
|
||||
scope : {
|
||||
entry : '='
|
||||
},
|
||||
replace : true,
|
||||
templateUrl : 'templates/_tags.html',
|
||||
controller : ['$scope', 'EntryService', function($scope, EntryService) {
|
||||
$scope.select2Options = {
|
||||
'multiple' : true,
|
||||
'simple_tags' : true,
|
||||
'maximumInputLength' : 40,
|
||||
tags : EntryService.tags
|
||||
};
|
||||
|
||||
$scope.$watch('entry.tags', function(newValue, oldValue) {
|
||||
if (oldValue && newValue != oldValue) {
|
||||
var data = {
|
||||
entryId : $scope.entry.id,
|
||||
tags : []
|
||||
};
|
||||
if (newValue) {
|
||||
data.tags = newValue.split(',');
|
||||
}
|
||||
EntryService.tag(data);
|
||||
}
|
||||
}, true);
|
||||
}]
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Reusable favicon component
|
||||
*/
|
||||
module.directive('favicon', function() {
|
||||
var tpl = '<img ng-src="{{url}}" class="favicon"></img>';
|
||||
return {
|
||||
restrict : 'E',
|
||||
scope : {
|
||||
url : '='
|
||||
},
|
||||
replace : true,
|
||||
template : tpl
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Support for the blur event
|
||||
*/
|
||||
module.directive('ngBlur', function() {
|
||||
return {
|
||||
restrict : 'A',
|
||||
link : function(scope, elm, attrs) {
|
||||
elm.bind('blur', function() {
|
||||
scope.$apply(attrs.ngBlur);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Prevent mousewheel scrolling from propagating to the parent when scrollbar
|
||||
* reaches top or bottom
|
||||
*/
|
||||
module.directive('mousewheelScrolling', function() {
|
||||
return {
|
||||
restrict : 'A',
|
||||
link : function(scope, elem, attr) {
|
||||
elem.bind('mousewheel', function(e, d) {
|
||||
var t = $(this);
|
||||
if (d > 0 && t.scrollTop() === 0) {
|
||||
e.preventDefault();
|
||||
} else {
|
||||
if (d < 0 && (t.scrollTop() == t.get(0).scrollHeight - t.innerHeight())) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Needed to use recursive directives. Wrap a recursive element with a
|
||||
* <recursive> tag
|
||||
*/
|
||||
module.directive('recursive', ['$compile', function($compile) {
|
||||
return {
|
||||
restrict : 'E',
|
||||
priority : 100000,
|
||||
compile : function(tElement, tAttr) {
|
||||
var contents = tElement.contents().remove();
|
||||
var compiledContents = null;
|
||||
return function(scope, iElement, iAttr) {
|
||||
if (!compiledContents) {
|
||||
compiledContents = $compile(contents);
|
||||
}
|
||||
iElement.append(compiledContents(scope, function(clone) {
|
||||
return clone;
|
||||
}));
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
/**
|
||||
* Reusable category component
|
||||
*/
|
||||
module.directive('category', [function() {
|
||||
return {
|
||||
scope : {
|
||||
node : '=',
|
||||
level : '=',
|
||||
selectedType : '=',
|
||||
selectedId : '=',
|
||||
showLabel : '=',
|
||||
showChildren : '=',
|
||||
unreadCount : '&',
|
||||
tag : '='
|
||||
},
|
||||
restrict : 'E',
|
||||
replace : true,
|
||||
templateUrl : 'templates/_category.html',
|
||||
controller : ['$scope', '$state', 'FeedService', 'CategoryService', 'SettingsService', 'MobileService',
|
||||
function($scope, $state, FeedService, CategoryService, SettingsService, MobileService) {
|
||||
$scope.settingsService = SettingsService;
|
||||
|
||||
$scope.getClass = function(level) {
|
||||
if ($scope.showLabel) {
|
||||
return 'indent' + level;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.categoryLabel = function(category) {
|
||||
return $scope.showLabel !== true ? $scope.showLabel : category.name;
|
||||
};
|
||||
|
||||
$scope.categoryCountLabel = function(category) {
|
||||
var count = $scope.unreadCount({
|
||||
category : category
|
||||
});
|
||||
var label = '';
|
||||
if (count > 0) {
|
||||
label = '(' + count + ')';
|
||||
}
|
||||
return label;
|
||||
};
|
||||
|
||||
$scope.feedCountLabel = function(feed) {
|
||||
var label = '';
|
||||
if (feed.unread > 0) {
|
||||
label = '(' + feed.unread + ')';
|
||||
}
|
||||
return label;
|
||||
};
|
||||
|
||||
$scope.feedClicked = function(id, event) {
|
||||
// Could be called by a middle click
|
||||
if (!event || (!event.ctrlKey && event.which == 1)) {
|
||||
MobileService.toggleLeftMenu();
|
||||
if ($scope.selectedType == 'feed' && id == $scope.selectedId) {
|
||||
$scope.$emit('emitReload');
|
||||
} else {
|
||||
$state.transitionTo('feeds.view', {
|
||||
_type : 'feed',
|
||||
_id : id
|
||||
});
|
||||
}
|
||||
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.categoryClicked = function(id, isTag) {
|
||||
MobileService.toggleLeftMenu();
|
||||
var type = isTag ? 'tag' : 'category';
|
||||
if ($scope.selectedType == type && id == $scope.selectedId) {
|
||||
$scope.$emit('emitReload');
|
||||
} else {
|
||||
$state.transitionTo('feeds.view', {
|
||||
_type : type,
|
||||
_id : id
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.showFeedDetails = function(feed) {
|
||||
$state.transitionTo('feeds.feed_details', {
|
||||
_id : feed.id
|
||||
});
|
||||
};
|
||||
|
||||
$scope.showCategoryDetails = function(id, isTag) {
|
||||
if (isTag) {
|
||||
$state.transitionTo('feeds.tag_details', {
|
||||
_id : id
|
||||
});
|
||||
} else {
|
||||
$state.transitionTo('feeds.category_details', {
|
||||
_id : id
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleCategory = function(category, event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
category.expanded = !category.expanded;
|
||||
if (category.id == 'all') {
|
||||
return;
|
||||
}
|
||||
CategoryService.collapse({
|
||||
id : category.id,
|
||||
collapse : !category.expanded
|
||||
});
|
||||
};
|
||||
}]
|
||||
};
|
||||
}]);
|
||||
|
||||
module.directive('draggable', function() {
|
||||
return {
|
||||
restrict : 'A',
|
||||
link : function(scope, element, attrs) {
|
||||
element.draggable({
|
||||
revert : 'invalid',
|
||||
helper : 'clone',
|
||||
distance : 10,
|
||||
axis : 'y'
|
||||
}).data('source', scope.$eval(attrs.draggable));
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.directive('droppable', ['CategoryService', 'FeedService', function(CategoryService, FeedService) {
|
||||
return {
|
||||
restrict : 'A',
|
||||
link : function(scope, element, attrs) {
|
||||
element.droppable({
|
||||
tolerance : 'pointer',
|
||||
over : function(event, ui) {
|
||||
|
||||
},
|
||||
drop : function(event, ui) {
|
||||
var draggable = angular.element(ui.draggable);
|
||||
|
||||
var source = draggable.data('source');
|
||||
var target = scope.$eval(attrs.droppable);
|
||||
|
||||
if (angular.equals(source, target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = {
|
||||
id : source.id,
|
||||
name : source.name
|
||||
};
|
||||
|
||||
if (source.children) {
|
||||
// source is a category
|
||||
|
||||
} else {
|
||||
// source is a feed
|
||||
|
||||
if (target.children) {
|
||||
// target is a category
|
||||
data.categoryId = target.id;
|
||||
data.position = 0;
|
||||
} else {
|
||||
// target is a feed
|
||||
data.categoryId = target.categoryId;
|
||||
data.position = target.position;
|
||||
}
|
||||
|
||||
FeedService.modify(data, function() {
|
||||
CategoryService.init();
|
||||
});
|
||||
}
|
||||
scope.$apply();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
module.directive('metricMeter', function() {
|
||||
return {
|
||||
scope : {
|
||||
metric : '=',
|
||||
label : '='
|
||||
},
|
||||
restrict : 'E',
|
||||
templateUrl : 'templates/_metrics.meter.html'
|
||||
};
|
||||
});
|
||||
|
||||
module.directive('metricGauge', function() {
|
||||
return {
|
||||
scope : {
|
||||
metric : '=',
|
||||
label : '='
|
||||
},
|
||||
restrict : 'E',
|
||||
templateUrl : 'templates/_metrics.gauge.html'
|
||||
};
|
||||
});
|
||||
113
src/main/app/js/filters.js
Normal file
113
src/main/app/js/filters.js
Normal file
@@ -0,0 +1,113 @@
|
||||
var module = angular.module('commafeed.filters', []);
|
||||
|
||||
/**
|
||||
* smart date formatter
|
||||
*/
|
||||
module.filter('entryDate', function() {
|
||||
return function(timestamp, defaultValue) {
|
||||
if (!timestamp) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
var d = moment(timestamp);
|
||||
var now = moment();
|
||||
var formatted;
|
||||
if (Math.abs(d.diff(now)) < 86400000) {
|
||||
formatted = d.fromNow();
|
||||
} else {
|
||||
formatted = d.format('YYYY-MM-DD HH:mm');
|
||||
}
|
||||
return formatted;
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* rewrites iframes to use https if commafeed uses https
|
||||
*/
|
||||
module.filter('iframeHttpsRewrite', function() {
|
||||
return function(html) {
|
||||
var result = html;
|
||||
if (location.protocol === 'https:') {
|
||||
var wrapper = $('<div></div>').html(html);
|
||||
$('iframe', wrapper).each(function(i, elem) {
|
||||
var e = $(elem);
|
||||
e.attr('src', e.attr('src').replace(/^http:\/\//i, 'https://'));
|
||||
});
|
||||
result = wrapper.html();
|
||||
}
|
||||
return result;
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* inserts title or alt-text after images, if any
|
||||
*/
|
||||
module.filter('appendImageTitles', function() {
|
||||
return function(html) {
|
||||
var result = html;
|
||||
var wrapper = $('<div></div>').html(html);
|
||||
$('img', wrapper).each(function(i, elem) {
|
||||
var e = $(elem);
|
||||
var title = e.attr('title') || e.attr('alt');
|
||||
if (title) {
|
||||
var text = $('<span style="font-style: italic;"></span>').text(title);
|
||||
e.after(text);
|
||||
}
|
||||
});
|
||||
result = wrapper.html();
|
||||
return result;
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* escapes the url
|
||||
*/
|
||||
module.filter('escape', function() {
|
||||
return encodeURIComponent;
|
||||
});
|
||||
|
||||
/**
|
||||
* returns a trusted html content
|
||||
*/
|
||||
module.filter('trustHtml', ['$sce', function($sce) {
|
||||
return function(val) {
|
||||
return $sce.trustAsHtml(val);
|
||||
};
|
||||
}]);
|
||||
|
||||
/**
|
||||
* returns a trusted url
|
||||
*/
|
||||
module.filter('trustUrl', ['$sce', function($sce) {
|
||||
return function(val) {
|
||||
return $sce.trustAsResourceUrl(val);
|
||||
};
|
||||
}]);
|
||||
|
||||
/**
|
||||
* add the 'highlight-search' class to text matching keywords
|
||||
*/
|
||||
module.filter('highlight', function() {
|
||||
return function(html, keywords) {
|
||||
if (keywords) {
|
||||
var handleKeyword = function(token, html) {
|
||||
var expr = new RegExp(token, 'gi');
|
||||
var container = $('<span>').html(html);
|
||||
var elements = container.find('*').addBack();
|
||||
var textNodes = elements.not('iframe').contents().not(elements);
|
||||
textNodes.each(function() {
|
||||
var replaced = this.nodeValue.replace(expr, '<span class="highlight-search">$&</span>');
|
||||
$('<span>').html(replaced).insertBefore(this);
|
||||
$(this).remove();
|
||||
});
|
||||
return container.html();
|
||||
};
|
||||
|
||||
var tokens = keywords.split(' ');
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
html = handleKeyword(tokens[i], html);
|
||||
}
|
||||
}
|
||||
return html;
|
||||
};
|
||||
});
|
||||
131
src/main/app/js/main.js
Normal file
131
src/main/app/js/main.js
Normal file
@@ -0,0 +1,131 @@
|
||||
var app = angular.module('commafeed', ['ngRoute', 'ngTouch', 'ngAnimate', 'ui.utils', 'ui.bootstrap', 'ui.router', 'ui.select2',
|
||||
'commafeed.directives', 'commafeed.controllers', 'commafeed.services', 'commafeed.filters', 'ngSanitize', 'infinite-scroll',
|
||||
'ngGrid', 'chieffancypants.loadingBar']);
|
||||
|
||||
app.config(['$routeProvider', '$stateProvider', '$urlRouterProvider', '$httpProvider', '$compileProvider', 'cfpLoadingBarProvider',
|
||||
function($routeProvider, $stateProvider, $urlRouterProvider, $httpProvider, $compileProvider, cfpLoadingBarProvider) {
|
||||
|
||||
cfpLoadingBarProvider.includeSpinner = false;
|
||||
|
||||
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|javascript):/);
|
||||
var interceptor = ['$rootScope', '$q', function(scope, $q) {
|
||||
|
||||
var success = function(response) {
|
||||
return response;
|
||||
};
|
||||
var error = function(response) {
|
||||
var status = response.status;
|
||||
if (status == 401) {
|
||||
window.location = 'logout';
|
||||
return;
|
||||
} else {
|
||||
return $q.reject(response);
|
||||
}
|
||||
};
|
||||
|
||||
var promise = function(promise) {
|
||||
return promise.then(success, error);
|
||||
};
|
||||
|
||||
return promise;
|
||||
}];
|
||||
|
||||
$httpProvider.responseInterceptors.push(interceptor);
|
||||
|
||||
$stateProvider.state('feeds', {
|
||||
'abstract' : true,
|
||||
url : '/feeds',
|
||||
templateUrl : 'templates/feeds.html'
|
||||
});
|
||||
$stateProvider.state('feeds.view', {
|
||||
url : '/view/:_type/:_id',
|
||||
templateUrl : 'templates/feeds.view.html',
|
||||
controller : 'FeedListCtrl'
|
||||
});
|
||||
$stateProvider.state('feeds.subscribe', {
|
||||
url : '/subscribe',
|
||||
templateUrl : 'templates/feeds.subscribe.html',
|
||||
controller : 'SubscribeCtrl'
|
||||
});
|
||||
$stateProvider.state('feeds.new_category', {
|
||||
url : '/add_category',
|
||||
templateUrl : 'templates/feeds.new_category.html',
|
||||
controller : 'NewCategoryCtrl'
|
||||
});
|
||||
$stateProvider.state('feeds.import', {
|
||||
url : '/import',
|
||||
templateUrl : 'templates/feeds.import.html',
|
||||
controller : 'ImportCtrl'
|
||||
});
|
||||
$stateProvider.state('feeds.search', {
|
||||
url : '/search/:_keywords',
|
||||
templateUrl : 'templates/feeds.view.html',
|
||||
controller : 'FeedListCtrl'
|
||||
});
|
||||
$stateProvider.state('feeds.feed_details', {
|
||||
url : '/details/feed/:_id',
|
||||
templateUrl : 'templates/feeds.feed_details.html',
|
||||
controller : 'FeedDetailsCtrl'
|
||||
});
|
||||
$stateProvider.state('feeds.category_details', {
|
||||
url : '/details/category/:_id',
|
||||
templateUrl : 'templates/feeds.category_details.html',
|
||||
controller : 'CategoryDetailsCtrl'
|
||||
});
|
||||
$stateProvider.state('feeds.tag_details', {
|
||||
url : '/details/tag/:_id',
|
||||
templateUrl : 'templates/feeds.tag_details.html',
|
||||
controller : 'TagDetailsCtrl'
|
||||
});
|
||||
$stateProvider.state('feeds.help', {
|
||||
url : '/help',
|
||||
templateUrl : 'templates/feeds.help.html',
|
||||
controller : 'HelpController'
|
||||
});
|
||||
$stateProvider.state('feeds.settings', {
|
||||
url : '/settings',
|
||||
templateUrl : 'templates/settings.html',
|
||||
controller : 'SettingsCtrl'
|
||||
});
|
||||
$stateProvider.state('feeds.profile', {
|
||||
url : '/profile',
|
||||
templateUrl : 'templates/profile.html',
|
||||
controller : 'ProfileCtrl'
|
||||
});
|
||||
|
||||
$stateProvider.state('admin', {
|
||||
'abstract' : true,
|
||||
url : '/admin',
|
||||
templateUrl : 'templates/admin.html'
|
||||
});
|
||||
$stateProvider.state('admin.userlist', {
|
||||
url : '/user/list',
|
||||
templateUrl : 'templates/admin.userlist.html',
|
||||
controller : 'ManageUsersCtrl'
|
||||
});
|
||||
$stateProvider.state('admin.useradd', {
|
||||
url : '/user/add',
|
||||
templateUrl : 'templates/admin.useradd.html',
|
||||
controller : 'ManageUserCtrl'
|
||||
});
|
||||
$stateProvider.state('admin.useredit', {
|
||||
url : '/user/edit/:_id',
|
||||
templateUrl : 'templates/admin.useredit.html',
|
||||
controller : 'ManageUserCtrl'
|
||||
});
|
||||
$stateProvider.state('admin.settings', {
|
||||
url : '/settings',
|
||||
templateUrl : 'templates/admin.settings.html',
|
||||
controller : 'ManageSettingsCtrl'
|
||||
});
|
||||
$stateProvider.state('admin.metrics', {
|
||||
url : '/metrics',
|
||||
templateUrl : 'templates/admin.metrics.html',
|
||||
controller : 'MetricsCtrl'
|
||||
});
|
||||
|
||||
$urlRouterProvider.when('/', '/feeds/view/category/all');
|
||||
$urlRouterProvider.when('/admin', '/admin/settings');
|
||||
$urlRouterProvider.otherwise('/');
|
||||
|
||||
}]);
|
||||
323
src/main/app/js/services.js
Normal file
323
src/main/app/js/services.js
Normal file
@@ -0,0 +1,323 @@
|
||||
var module = angular.module('commafeed.services', ['ngResource']);
|
||||
|
||||
module.service('AnalyticsService', ['$state', function($state) {
|
||||
this.track = function(path) {
|
||||
if (typeof ga === 'undefined') {
|
||||
return;
|
||||
}
|
||||
path = path || $state.$current.url.prefix;
|
||||
ga('send', 'pageview', {
|
||||
page : path
|
||||
});
|
||||
};
|
||||
}]);
|
||||
|
||||
module.service('MobileService', ['$state', function($state) {
|
||||
this.leftMenu = false;
|
||||
this.rightMenu = false;
|
||||
this.toggleLeftMenu = function() {
|
||||
this.leftMenu = !this.leftMenu;
|
||||
$('body').toggleClass('left-menu-active');
|
||||
};
|
||||
this.toggleRightMenu = function() {
|
||||
this.rightMenu = !this.rightMenu;
|
||||
$('body').toggleClass('right-menu-active');
|
||||
};
|
||||
this.mobile = device.mobile() || device.tablet();
|
||||
}]);
|
||||
|
||||
module.factory('ProfileService', ['$resource', function($resource) {
|
||||
var res = $resource('rest/user/profile/');
|
||||
res.deleteAccount = $resource('rest/user/profile/deleteAccount').save;
|
||||
return res;
|
||||
}]);
|
||||
|
||||
module.factory('SettingsService', ['$resource', function($resource) {
|
||||
var res = $resource('rest/user/settings');
|
||||
|
||||
var s = {};
|
||||
s.settings = {};
|
||||
s.save = function(callback) {
|
||||
res.save(s.settings, function(data) {
|
||||
if (callback) {
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
};
|
||||
s.init = function(callback) {
|
||||
res.get(function(data) {
|
||||
s.settings = data;
|
||||
var lang = s.settings.language || 'en';
|
||||
if (lang === 'zh') {
|
||||
lang = 'zh-cn';
|
||||
} else if (lang === 'ms') {
|
||||
lang = 'ms-my';
|
||||
}
|
||||
moment.lang(lang, {});
|
||||
if (callback) {
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
};
|
||||
s.init();
|
||||
return s;
|
||||
}]);
|
||||
|
||||
module.factory('FeedService', ['$resource', '$http', function($resource, $http) {
|
||||
var actions = {
|
||||
entries : {
|
||||
method : 'GET',
|
||||
params : {
|
||||
_method : 'entries'
|
||||
}
|
||||
},
|
||||
fetch : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'fetch'
|
||||
}
|
||||
},
|
||||
mark : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'mark'
|
||||
}
|
||||
},
|
||||
refresh : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'refresh'
|
||||
}
|
||||
},
|
||||
refreshAll : {
|
||||
method : 'GET',
|
||||
params : {
|
||||
_method : 'refreshAll'
|
||||
}
|
||||
},
|
||||
subscribe : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'subscribe'
|
||||
}
|
||||
},
|
||||
unsubscribe : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'unsubscribe'
|
||||
}
|
||||
},
|
||||
modify : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'modify'
|
||||
}
|
||||
}
|
||||
};
|
||||
var res = $resource('rest/feed/:_method', {}, actions);
|
||||
res.get = $resource('rest/feed/get/:id').get;
|
||||
return res;
|
||||
}]);
|
||||
|
||||
module.factory('CategoryService', ['$resource', '$http', function($resource, $http) {
|
||||
|
||||
var traverse = function(callback, category, parentName) {
|
||||
callback(category, parentName);
|
||||
var children = category.children;
|
||||
if (children) {
|
||||
for (var c = 0; c < children.length; c++) {
|
||||
traverse(callback, children[c], category.name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// flatten categories
|
||||
var flatten = function(category) {
|
||||
var array = [];
|
||||
var callback = function(category, parentName) {
|
||||
var name = category.name;
|
||||
if (parentName) {
|
||||
name += (' (in ' + parentName + ')');
|
||||
}
|
||||
array.push({
|
||||
id : category.id,
|
||||
name : name,
|
||||
orig : category
|
||||
});
|
||||
};
|
||||
traverse(callback, category);
|
||||
return array;
|
||||
};
|
||||
|
||||
// flatten feeds
|
||||
var flatFeeds = function(category) {
|
||||
var subs = [];
|
||||
var callback = function(category) {
|
||||
subs.push.apply(subs, category.feeds);
|
||||
};
|
||||
traverse(callback, category);
|
||||
return subs;
|
||||
};
|
||||
|
||||
// flatten everything
|
||||
var flatAll = function(category, a) {
|
||||
a.push([category.id, 'category']);
|
||||
_.each(category.children, function(child) {
|
||||
flatAll(child, a);
|
||||
});
|
||||
_.each(category.feeds, function(feed) {
|
||||
a.push([feed.id, 'feed']);
|
||||
});
|
||||
};
|
||||
|
||||
var actions = {
|
||||
get : {
|
||||
method : 'GET',
|
||||
ignoreLoadingBar: true,
|
||||
params : {
|
||||
_method : 'get'
|
||||
}
|
||||
},
|
||||
entries : {
|
||||
method : 'GET',
|
||||
params : {
|
||||
_method : 'entries'
|
||||
}
|
||||
},
|
||||
mark : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'mark'
|
||||
}
|
||||
},
|
||||
add : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'add'
|
||||
}
|
||||
},
|
||||
remove : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'delete'
|
||||
}
|
||||
},
|
||||
modify : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'modify'
|
||||
}
|
||||
},
|
||||
collapse : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'collapse'
|
||||
}
|
||||
}
|
||||
};
|
||||
var res = $resource('rest/category/:_method', {}, actions);
|
||||
res.subscriptions = {};
|
||||
res.flatCategories = {};
|
||||
res.feeds = [];
|
||||
|
||||
res.init = function(callback) {
|
||||
res.get(function(data) {
|
||||
res.subscriptions = data;
|
||||
res.flatCategories = flatten(data);
|
||||
res.feeds = flatFeeds(data);
|
||||
|
||||
res.flatAll = [];
|
||||
flatAll(data, res.flatAll);
|
||||
res.flatAll.splice(1, 0, ['starred', 'category']);
|
||||
|
||||
if (callback)
|
||||
callback(data);
|
||||
});
|
||||
};
|
||||
res.refresh = function(callback) {
|
||||
res.get(function(data) {
|
||||
_.merge(res.subscriptions, data);
|
||||
if (callback)
|
||||
callback(data);
|
||||
});
|
||||
};
|
||||
|
||||
res.init();
|
||||
return res;
|
||||
}]);
|
||||
|
||||
module.factory('EntryService', ['$resource', '$http', function($resource, $http) {
|
||||
var actions = {
|
||||
search : {
|
||||
method : 'GET',
|
||||
params : {
|
||||
_method : 'search'
|
||||
}
|
||||
},
|
||||
mark : {
|
||||
method : 'POST',
|
||||
ignoreLoadingBar: true,
|
||||
params : {
|
||||
_method : 'mark'
|
||||
}
|
||||
},
|
||||
markMultiple : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'markMultiple'
|
||||
}
|
||||
},
|
||||
star : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'star'
|
||||
}
|
||||
},
|
||||
tag : {
|
||||
method : 'POST',
|
||||
params : {
|
||||
_method : 'tag'
|
||||
}
|
||||
}
|
||||
};
|
||||
var res = $resource('rest/entry/:_method', {}, actions);
|
||||
res.tags = [];
|
||||
var initTags = function() {
|
||||
$http.get('rest/entry/tags').success(function(data) {
|
||||
res.tags = [];
|
||||
res.tags.push.apply(res.tags, data);
|
||||
});
|
||||
};
|
||||
var oldTag = res.tag;
|
||||
res.tag = function(data) {
|
||||
oldTag(data, function() {
|
||||
initTags();
|
||||
});
|
||||
};
|
||||
initTags();
|
||||
return res;
|
||||
}]);
|
||||
|
||||
module.factory('AdminUsersService', ['$resource', function($resource) {
|
||||
var res = {};
|
||||
res.get = $resource('rest/admin/user/get/:id').get;
|
||||
res.getAll = $resource('rest/admin/user/getAll').query;
|
||||
res.save = $resource('rest/admin/user/save').save;
|
||||
res.remove = $resource('rest/admin/user/delete').save;
|
||||
return res;
|
||||
}]);
|
||||
|
||||
module.factory('AdminSettingsService', ['$resource', function($resource) {
|
||||
var res = $resource('rest/admin/settings/');
|
||||
return res;
|
||||
}]);
|
||||
|
||||
module.factory('AdminMetricsService', ['$resource', function($resource) {
|
||||
var res = $resource('rest/admin/metrics/');
|
||||
return res;
|
||||
}]);
|
||||
|
||||
module.factory('ServerService', ['$resource', function($resource) {
|
||||
var res = $resource('rest/server/get');
|
||||
return res;
|
||||
}]);
|
||||
7
src/main/app/js/welcome.js
Normal file
7
src/main/app/js/welcome.js
Normal file
@@ -0,0 +1,7 @@
|
||||
$(function() {
|
||||
var reg = $('#register-panel');
|
||||
if (!reg) {
|
||||
return;
|
||||
}
|
||||
$('#login-panel').height(reg.height());
|
||||
});
|
||||
Reference in New Issue
Block a user