mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
Add Alphabetical sorting
First "working" version of Alphabetical sorting in Commafeed. Needs better front end interface, translations, and probably the API is buggy surrounding "order" now b/c there is probably some code still that assumes there are only two possible ways to sort (date asc, date desc).
This commit is contained in:
@@ -531,7 +531,11 @@ module.controller('ToolbarCtrl', [
|
|||||||
|
|
||||||
$scope.toggleOrder = function() {
|
$scope.toggleOrder = function() {
|
||||||
var settings = $scope.settingsService.settings;
|
var settings = $scope.settingsService.settings;
|
||||||
settings.readingOrder = settings.readingOrder == 'asc' ? 'desc' : 'asc';
|
settings.readingOrder = settings.readingOrder == 'desc' ? 'asc' : 'desc';
|
||||||
|
};
|
||||||
|
$scope.toggleAbcOrder = function() {
|
||||||
|
var settings = $scope.settingsService.settings;
|
||||||
|
settings.readingOrder = settings.readingOrder == 'abc' ? 'zyx' : 'abc';
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.toAdmin = function() {
|
$scope.toAdmin = function() {
|
||||||
|
|||||||
@@ -69,7 +69,11 @@
|
|||||||
<div class="btn-group" id="toolbar-read-order">
|
<div class="btn-group" id="toolbar-read-order">
|
||||||
<a type="button" class="btn btn-default" ng-click="toggleOrder()" title="{{ 'toolbar.sort_by_asc_desc' | translate }}">
|
<a type="button" class="btn btn-default" ng-click="toggleOrder()" title="{{ 'toolbar.sort_by_asc_desc' | translate }}">
|
||||||
<i
|
<i
|
||||||
ng-class="{'icon-arrow-up' : settingsService.settings.readingOrder == 'asc', 'icon-arrow-down': settingsService.settings.readingOrder == 'desc'}"></i>
|
ng-class="{'icon-arrow-up' : settingsService.settings.readingOrder == 'asc', 'icon-arrow-down': settingsService.settings.readingOrder != 'asc'}"></i>
|
||||||
|
</a>
|
||||||
|
<a type="button" class="btn btn-default" ng-click="toggleAbcOrder()" title="{{ 'toolbar.sort_by_asc_desc' | translate }}">
|
||||||
|
<i
|
||||||
|
ng-class="{'icon-arrow-up' : settingsService.settings.readingOrder == 'abc', 'icon-arrow-down': settingsService.settings.readingOrder != 'abc'}"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,19 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ASC = Ordering.from(STATUS_COMPARATOR_DESC).reverse();
|
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ASC = Ordering.from(STATUS_COMPARATOR_DESC).reverse();
|
||||||
|
|
||||||
|
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ABC = new Comparator<FeedEntryStatus>() {
|
||||||
|
@Override
|
||||||
|
public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
|
||||||
|
CompareToBuilder builder = new CompareToBuilder();
|
||||||
|
builder.append(o2.getTitle(), o1.getTitle());
|
||||||
|
builder.append(o2.getId(), o1.getId());
|
||||||
|
return builder.toComparison();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ZYX = Ordering.from(STATUS_COMPARATOR_ABC).reverse();
|
||||||
|
|
||||||
|
|
||||||
public FeedEntryStatus getStatus(User user, FeedSubscription sub, FeedEntry entry) {
|
public FeedEntryStatus getStatus(User user, FeedSubscription sub, FeedEntry entry) {
|
||||||
List<FeedEntryStatus> statuses = query().selectFrom(status).where(status.entry.eq(entry), status.subscription.eq(sub)).fetch();
|
List<FeedEntryStatus> statuses = query().selectFrom(status).where(status.entry.eq(entry), status.subscription.eq(sub)).fetch();
|
||||||
@@ -172,8 +185,14 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
if (order != null) {
|
if (order != null) {
|
||||||
if (order == ReadingOrder.asc) {
|
if (order == ReadingOrder.asc) {
|
||||||
query.orderBy(entry.updated.asc(), entry.id.asc());
|
query.orderBy(entry.updated.asc(), entry.id.asc());
|
||||||
} else {
|
} else if (order == ReadingOrder.desc) {
|
||||||
query.orderBy(entry.updated.desc(), entry.id.desc());
|
query.orderBy(entry.updated.desc(), entry.id.desc());
|
||||||
|
} else if (order == ReadingOrder.abc) {
|
||||||
|
query.join(entry.content, content);
|
||||||
|
query.orderBy(content.title.desc(), entry.id.desc());
|
||||||
|
} else { //order == ReadingOrder.zyx
|
||||||
|
query.join(entry.content, content);
|
||||||
|
query.orderBy(content.title.asc(), entry.id.asc());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (offset > -1) {
|
if (offset > -1) {
|
||||||
@@ -193,17 +212,33 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
List<FeedEntryKeyword> keywords, Date newerThan, int offset, int limit, ReadingOrder order, boolean includeContent,
|
List<FeedEntryKeyword> keywords, Date newerThan, int offset, int limit, ReadingOrder order, boolean includeContent,
|
||||||
boolean onlyIds, String tag) {
|
boolean onlyIds, String tag) {
|
||||||
int capacity = offset + limit;
|
int capacity = offset + limit;
|
||||||
Comparator<FeedEntryStatus> comparator = order == ReadingOrder.desc ? STATUS_COMPARATOR_DESC : STATUS_COMPARATOR_ASC;
|
|
||||||
|
Comparator<FeedEntryStatus> comparator;
|
||||||
|
if (order == ReadingOrder.desc) {
|
||||||
|
comparator = STATUS_COMPARATOR_DESC;
|
||||||
|
} else if (order == ReadingOrder.abc) {
|
||||||
|
comparator = STATUS_COMPARATOR_ABC;
|
||||||
|
} else if (order == ReadingOrder.zyx) {
|
||||||
|
comparator = STATUS_COMPARATOR_ZYX;
|
||||||
|
} else {
|
||||||
|
comparator = STATUS_COMPARATOR_ASC;
|
||||||
|
}
|
||||||
|
|
||||||
FixedSizeSortedSet<FeedEntryStatus> set = new FixedSizeSortedSet<FeedEntryStatus>(capacity, comparator);
|
FixedSizeSortedSet<FeedEntryStatus> set = new FixedSizeSortedSet<FeedEntryStatus>(capacity, comparator);
|
||||||
for (FeedSubscription sub : subs) {
|
for (FeedSubscription sub : subs) {
|
||||||
Date last = (order != null && set.isFull()) ? set.last().getEntryUpdated() : null;
|
Date last = (order != null && set.isFull()) ? set.last().getEntryUpdated() : null;
|
||||||
HibernateQuery<FeedEntry> query = buildQuery(user, sub, unreadOnly, keywords, newerThan, -1, capacity, order, last, tag);
|
HibernateQuery<FeedEntry> query = buildQuery(user, sub, unreadOnly, keywords, newerThan, -1, capacity, order, last, tag);
|
||||||
List<Tuple> tuples = query.select(entry.id, entry.updated, status.id).fetch();
|
List<Tuple> tuples;
|
||||||
|
if (order == ReadingOrder.abc || order == ReadingOrder.zyx) {
|
||||||
|
tuples = query.select(entry.id, entry.updated, status.id, content.title).fetch();
|
||||||
|
} else {
|
||||||
|
tuples = query.select(entry.id, entry.updated, status.id).fetch();
|
||||||
|
}
|
||||||
for (Tuple tuple : tuples) {
|
for (Tuple tuple : tuples) {
|
||||||
Long id = tuple.get(entry.id);
|
Long id = tuple.get(entry.id);
|
||||||
Date updated = tuple.get(entry.updated);
|
Date updated = tuple.get(entry.updated);
|
||||||
Long statusId = tuple.get(status.id);
|
Long statusId = tuple.get(status.id);
|
||||||
|
|
||||||
FeedEntry entry = new FeedEntry();
|
FeedEntry entry = new FeedEntry();
|
||||||
entry.setId(id);
|
entry.setId(id);
|
||||||
entry.setUpdated(updated);
|
entry.setUpdated(updated);
|
||||||
@@ -213,6 +248,11 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
status.setEntryUpdated(updated);
|
status.setEntryUpdated(updated);
|
||||||
status.setEntry(entry);
|
status.setEntry(entry);
|
||||||
status.setSubscription(sub);
|
status.setSubscription(sub);
|
||||||
|
|
||||||
|
if (order == ReadingOrder.abc || order == ReadingOrder.zyx) {
|
||||||
|
String title = tuple.get(content.title);
|
||||||
|
status.setTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
set.add(status);
|
set.add(status);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ public class FeedEntryStatus extends AbstractModel {
|
|||||||
|
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
private Date entryUpdated;
|
private Date entryUpdated;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
public FeedEntryStatus() {
|
public FeedEntryStatus() {
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class UserSettings extends AbstractModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum ReadingOrder {
|
public enum ReadingOrder {
|
||||||
asc, desc
|
asc, desc, abc, zyx
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ViewMode {
|
public enum ViewMode {
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ public class CategoryREST {
|
|||||||
@ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan,
|
@ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan,
|
||||||
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset,
|
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset,
|
||||||
@ApiParam(value = "limit for paging, default 20, maximum 1000") @DefaultValue("20") @QueryParam("limit") int limit,
|
@ApiParam(value = "limit for paging, default 20, maximum 1000") @DefaultValue("20") @QueryParam("limit") int limit,
|
||||||
@ApiParam(value = "date ordering", allowableValues = "asc,desc") @QueryParam("order") @DefaultValue("desc") ReadingOrder order,
|
@ApiParam(value = "ordering", allowableValues = "asc,desc,abc,zyx") @QueryParam("order") @DefaultValue("desc") ReadingOrder order,
|
||||||
@ApiParam(
|
@ApiParam(
|
||||||
value = "search for keywords in either the title or the content of the entries, separated by spaces, 3 characters minimum") @QueryParam("keywords") String keywords,
|
value = "search for keywords in either the title or the content of the entries, separated by spaces, 3 characters minimum") @QueryParam("keywords") String keywords,
|
||||||
@ApiParam(value = "return only entry ids") @DefaultValue("false") @QueryParam("onlyIds") boolean onlyIds,
|
@ApiParam(value = "return only entry ids") @DefaultValue("false") @QueryParam("onlyIds") boolean onlyIds,
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ public class FeedREST {
|
|||||||
@ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan,
|
@ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan,
|
||||||
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset,
|
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset,
|
||||||
@ApiParam(value = "limit for paging, default 20, maximum 1000") @DefaultValue("20") @QueryParam("limit") int limit,
|
@ApiParam(value = "limit for paging, default 20, maximum 1000") @DefaultValue("20") @QueryParam("limit") int limit,
|
||||||
@ApiParam(value = "date ordering", allowableValues = "asc,desc") @QueryParam("order") @DefaultValue("desc") ReadingOrder order,
|
@ApiParam(value = "ordering", allowableValues = "asc,desc,abc,zyx") @QueryParam("order") @DefaultValue("desc") ReadingOrder order,
|
||||||
@ApiParam(
|
@ApiParam(
|
||||||
value = "search for keywords in either the title or the content of the entries, separated by spaces, 3 characters minimum") @QueryParam("keywords") String keywords,
|
value = "search for keywords in either the title or the content of the entries, separated by spaces, 3 characters minimum") @QueryParam("keywords") String keywords,
|
||||||
@ApiParam(value = "return only entry ids") @DefaultValue("false") @QueryParam("onlyIds") boolean onlyIds) {
|
@ApiParam(value = "return only entry ids") @DefaultValue("false") @QueryParam("onlyIds") boolean onlyIds) {
|
||||||
|
|||||||
Reference in New Issue
Block a user