mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
handle 'mark as read'
This commit is contained in:
@@ -1,10 +1,30 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import javax.ejb.Stateless;
|
import javax.ejb.Stateless;
|
||||||
|
import javax.persistence.NoResultException;
|
||||||
|
|
||||||
|
import com.commafeed.backend.model.FeedEntry;
|
||||||
import com.commafeed.backend.model.FeedEntryStatus;
|
import com.commafeed.backend.model.FeedEntryStatus;
|
||||||
|
import com.commafeed.backend.model.User;
|
||||||
|
import com.commafeed.frontend.utils.ModelFactory.MF;
|
||||||
|
import com.uaihebert.factory.EasyCriteriaFactory;
|
||||||
|
import com.uaihebert.model.EasyCriteria;
|
||||||
|
|
||||||
@Stateless
|
@Stateless
|
||||||
public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus, Long> {
|
public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus, Long> {
|
||||||
|
|
||||||
|
public FeedEntryStatus getStatus(User user, FeedEntry entry) {
|
||||||
|
EasyCriteria<FeedEntryStatus> criteria = EasyCriteriaFactory
|
||||||
|
.createQueryCriteria(em, getType());
|
||||||
|
criteria.andEquals(MF.i(proxy().getUser()), user);
|
||||||
|
criteria.andEquals(MF.i(proxy().getEntry()), entry);
|
||||||
|
|
||||||
|
FeedEntryStatus status = null;
|
||||||
|
try {
|
||||||
|
criteria.getSingleResult();
|
||||||
|
} catch (NoResultException e) {
|
||||||
|
status = null;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import javax.persistence.criteria.CriteriaBuilder;
|
|||||||
import javax.persistence.criteria.CriteriaQuery;
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
|
import com.commafeed.frontend.utils.ModelFactory.MF;
|
||||||
import com.google.common.reflect.TypeToken;
|
import com.google.common.reflect.TypeToken;
|
||||||
import com.uaihebert.factory.EasyCriteriaFactory;
|
import com.uaihebert.factory.EasyCriteriaFactory;
|
||||||
import com.uaihebert.model.EasyCriteria;
|
import com.uaihebert.model.EasyCriteria;
|
||||||
@@ -88,4 +89,8 @@ public abstract class GenericDAO<T, K> implements Serializable {
|
|||||||
return (Class<T>) type.getRawType();
|
return (Class<T>) type.getRawType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected T proxy() {
|
||||||
|
return MF.p(getType());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.util.Set;
|
|||||||
import javax.ws.rs.ApplicationPath;
|
import javax.ws.rs.ApplicationPath;
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
||||||
|
|
||||||
|
import com.commafeed.frontend.rest.resources.AbstractREST;
|
||||||
import com.commafeed.frontend.rest.resources.EntriesREST;
|
import com.commafeed.frontend.rest.resources.EntriesREST;
|
||||||
import com.commafeed.frontend.rest.resources.SubscriptionsREST;
|
import com.commafeed.frontend.rest.resources.SubscriptionsREST;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
@@ -17,6 +18,7 @@ public class RESTApplication extends Application {
|
|||||||
Set<Class<?>> set = Sets.newHashSet();
|
Set<Class<?>> set = Sets.newHashSet();
|
||||||
set.add(JSONMessageBodyWriter.class);
|
set.add(JSONMessageBodyWriter.class);
|
||||||
|
|
||||||
|
set.add(AbstractREST.class);
|
||||||
set.add(SubscriptionsREST.class);
|
set.add(SubscriptionsREST.class);
|
||||||
set.add(EntriesREST.class);
|
set.add(EntriesREST.class);
|
||||||
return set;
|
return set;
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import javax.inject.Inject;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
import org.apache.wicket.Application;
|
import org.apache.wicket.Application;
|
||||||
import org.apache.wicket.ThreadContext;
|
import org.apache.wicket.ThreadContext;
|
||||||
@@ -51,6 +53,10 @@ public abstract class AbstractREST {
|
|||||||
ThreadContext.setRequestCycle(cycle);
|
ThreadContext.setRequestCycle(cycle);
|
||||||
Application.get().fetchCreateAndSetSession(
|
Application.get().fetchCreateAndSetSession(
|
||||||
Application.get().createRequestCycle(swreq, swresp));
|
Application.get().createRequestCycle(swreq, swresp));
|
||||||
|
|
||||||
|
if (getUser() == null) {
|
||||||
|
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected User getUser() {
|
protected User getUser() {
|
||||||
|
|||||||
@@ -93,4 +93,26 @@ public class EntriesREST extends AbstractREST {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Path("mark/{type}/{id}/{read}")
|
||||||
|
@GET
|
||||||
|
public void mark(@PathParam("type") String type,
|
||||||
|
@PathParam("id") String id, @PathParam("read") boolean read) {
|
||||||
|
if ("entry".equals(type)) {
|
||||||
|
FeedEntry entry = feedEntryService.findById(Long.valueOf(id));
|
||||||
|
FeedEntryStatus status = feedEntryStatusService.getStatus(
|
||||||
|
getUser(), entry);
|
||||||
|
if (status == null) {
|
||||||
|
status = new FeedEntryStatus();
|
||||||
|
status.setUser(getUser());
|
||||||
|
status.setEntry(entry);
|
||||||
|
}
|
||||||
|
status.setRead(read);
|
||||||
|
if (status.getId() == null) {
|
||||||
|
feedEntryStatusService.save(status);
|
||||||
|
} else {
|
||||||
|
feedEntryStatusService.update(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
var module = angular.module('commafeed.controllers', []);
|
var module = angular.module('commafeed.controllers', []);
|
||||||
|
|
||||||
module.run(function($rootScope) {
|
module.run(function($rootScope) {
|
||||||
$rootScope.$on('emitMarkAsRead', function(event, args) {
|
$rootScope.$on('emitMark', function(event, args) {
|
||||||
$rootScope.$broadcast('markAsRead', args);
|
// args.entry - the entry
|
||||||
|
$rootScope.$broadcast('mark', args);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -57,25 +58,25 @@ module.controller('CategoryTreeCtrl', function($scope, $routeParams, $location,
|
|||||||
$location.path('/feeds/view/category/' + id);
|
$location.path('/feeds/view/category/' + id);
|
||||||
};
|
};
|
||||||
|
|
||||||
var markAsRead = function(node, entry, read) {
|
var mark = function(node, entry) {
|
||||||
if (node.children) {
|
if (node.children) {
|
||||||
for ( var i = 0; i < node.children.length; i++) {
|
for ( var i = 0; i < node.children.length; i++) {
|
||||||
markAsRead(node.children[i], entry, read);
|
mark(node.children[i], entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node.feeds) {
|
if (node.feeds) {
|
||||||
for ( var i = 0; i < node.feeds.length; i++) {
|
for ( var i = 0; i < node.feeds.length; i++) {
|
||||||
var feed = node.feeds[i];
|
var feed = node.feeds[i];
|
||||||
if (feed.id == entry.feedId) {
|
if (feed.id == entry.feedId) {
|
||||||
var c = read ? -1 : 1;
|
var c = entry.read ? -1 : 1;
|
||||||
feed.unread = feed.unread + c;
|
feed.unread = feed.unread + c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.$on('markAsRead', function(event, args) {
|
$scope.$on('mark', function(event, args) {
|
||||||
markAsRead($scope.root, args.entry, args.read)
|
mark($scope.root, args.entry)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -85,44 +86,22 @@ module.controller('FeedListCtrl', function($scope, $routeParams, $http,
|
|||||||
$scope.selectedType = $routeParams._type;
|
$scope.selectedType = $routeParams._type;
|
||||||
$scope.selectedId = $routeParams._id;
|
$scope.selectedId = $routeParams._id;
|
||||||
|
|
||||||
$scope.entryList = EntryService.getUnread({
|
$scope.entryList = EntryService.get({
|
||||||
_type : $scope.selectedType,
|
_type : $scope.selectedType,
|
||||||
_id : $scope.selectedId,
|
_id : $scope.selectedId,
|
||||||
_readtype : 'unread'
|
_readtype : 'unread'
|
||||||
})
|
})
|
||||||
|
|
||||||
$scope.entryList2 = {
|
$scope.mark = function(entry, read) {
|
||||||
name : 'aaa',
|
|
||||||
entries : [ {
|
|
||||||
id : '1',
|
|
||||||
title : 'my title',
|
|
||||||
content : 'my content',
|
|
||||||
date : 'my date',
|
|
||||||
feedId : '1',
|
|
||||||
feedName : 'my feed',
|
|
||||||
url : 'my url',
|
|
||||||
read : false,
|
|
||||||
starred : false,
|
|
||||||
}, {
|
|
||||||
id : '2',
|
|
||||||
title : 'my other title',
|
|
||||||
content : 'my other content',
|
|
||||||
date : 'my other date',
|
|
||||||
feedId : '2',
|
|
||||||
feedName : 'my other feed',
|
|
||||||
url : 'my other url',
|
|
||||||
read : false,
|
|
||||||
starred : false,
|
|
||||||
} ]
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.markAsRead = function(entry) {
|
|
||||||
var read = entry.read;
|
|
||||||
entry.read = true;
|
|
||||||
if (entry.read != read) {
|
if (entry.read != read) {
|
||||||
$scope.$emit('emitMarkAsRead', {
|
entry.read = read;
|
||||||
entry : entry,
|
$scope.$emit('emitMark', {
|
||||||
read : true
|
entry : entry
|
||||||
|
});
|
||||||
|
EntryService.mark({
|
||||||
|
_type : 'entry',
|
||||||
|
_id : entry.id,
|
||||||
|
_readtype : read
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,21 +6,30 @@ module.factory('CategoryService', [ '$resource', '$http',
|
|||||||
'get' : {
|
'get' : {
|
||||||
method : 'GET'
|
method : 'GET'
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
res = $resource('rest/subscriptions', {}, actions);
|
res = $resource('rest/subscriptions', {}, actions);
|
||||||
return res
|
return res;
|
||||||
} ]);
|
} ]);
|
||||||
|
|
||||||
module.factory('EntryService', [ '$resource', '$http',
|
module.factory('EntryService', [
|
||||||
|
'$resource',
|
||||||
|
'$http',
|
||||||
function($resource, $http) {
|
function($resource, $http) {
|
||||||
var actions = {
|
var actions = {
|
||||||
'getUnread' : {
|
'get' : {
|
||||||
method : 'GET',
|
method : 'GET',
|
||||||
params : {
|
params : {
|
||||||
_method : 'get'
|
_method : 'get'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mark : {
|
||||||
|
method : 'GET',
|
||||||
|
params : {
|
||||||
|
_method : 'mark'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
res = $resource('rest/entries/:_method/:_type/:_id/:_readtype', {}, actions);
|
res = $resource('rest/entries/:_method/:_type/:_id/:_readtype', {},
|
||||||
return res
|
actions);
|
||||||
|
return res;
|
||||||
} ]);
|
} ]);
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<div class="accordion-group" ng-repeat="entry in entryList.entries">
|
<div class="accordion-group" ng-repeat="entry in entryList.entries">
|
||||||
<div class="accordion-heading">
|
<div class="accordion-heading">
|
||||||
<a class="accordion-toggle" data-toggle="collapse"
|
<a class="accordion-toggle" data-toggle="collapse"
|
||||||
ng-click="markAsRead(entry)"
|
ng-click="mark(entry, true)"
|
||||||
ng-class="{unread: entry.read == false}"
|
ng-class="{unread: entry.read == false}"
|
||||||
data-parent="#feed-accordion" href="{{'#feed-body' + $index}}">
|
data-parent="#feed-accordion" href="{{'#feed-body' + $index}}">
|
||||||
<span ng-show="selectedType == 'category'">{{entry.feedName}}
|
<span ng-show="selectedType == 'category'">{{entry.feedName}}
|
||||||
|
|||||||
Reference in New Issue
Block a user