Allow sorting and filtering of “known Sones.”
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Mon, 20 Jun 2011 05:56:36 +0000 (07:56 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Mon, 20 Jun 2011 05:56:48 +0000 (07:56 +0200)
This fixes #18.

src/main/java/net/pterodactylus/sone/data/Sone.java
src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java
src/main/resources/static/css/sone.css
src/main/resources/templates/knownSones.html

index e1c0391..ca87856 100644 (file)
@@ -60,6 +60,17 @@ public class Sone implements Fingerprintable, Comparable<Sone> {
 
        };
 
+       /**
+        * Comparator that sorts Sones by last activity (least recent active first).
+        */
+       public static final Comparator<Sone> LAST_ACTIVITY_COMPARATOR = new Comparator<Sone>() {
+
+               @Override
+               public int compare(Sone firstSone, Sone secondSone) {
+                       return (int) Math.min(Integer.MAX_VALUE, Math.max(Integer.MIN_VALUE, secondSone.getTime() - firstSone.getTime()));
+               }
+       };
+
        /** Filter to remove Sones that have not been downloaded. */
        public static final Filter<Sone> EMPTY_SONE_FILTER = new Filter<Sone>() {
 
index 7c8f9ad..0e42eb5 100644 (file)
@@ -23,6 +23,8 @@ import java.util.List;
 
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.util.collection.Pagination;
+import net.pterodactylus.util.collection.ReverseComparator;
+import net.pterodactylus.util.filter.Filter;
 import net.pterodactylus.util.filter.Filters;
 import net.pterodactylus.util.number.Numbers;
 import net.pterodactylus.util.template.Template;
@@ -57,11 +59,49 @@ public class KnownSonesPage extends SoneTemplatePage {
        @Override
        protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException {
                super.processTemplate(request, templateContext);
+               String sortField = request.getHttpRequest().getParam("sort");
+               String sortOrder = request.getHttpRequest().getParam("order");
+               String followedSones = request.getHttpRequest().getParam("followedSones");
+               final Sone currentSone = getCurrentSone(request.getToadletContext(), false);
                List<Sone> knownSones = Filters.filteredList(new ArrayList<Sone>(webInterface.getCore().getSones()), Sone.EMPTY_SONE_FILTER);
-               Collections.sort(knownSones, Sone.NICE_NAME_COMPARATOR);
+               if ((currentSone != null) && "show-only".equals(followedSones)) {
+                       knownSones = Filters.filteredList(knownSones, new Filter<Sone>() {
+
+                               @Override
+                               public boolean filterObject(Sone sone) {
+                                       return currentSone.hasFriend(sone.getId());
+                               }
+                       });
+                       templateContext.set("followedSones", "show-only");
+               } else if ((currentSone != null) && "hide".equals(followedSones)) {
+                       knownSones = Filters.filteredList(knownSones, new Filter<Sone>() {
+
+                               @Override
+                               public boolean filterObject(Sone sone) {
+                                       return !currentSone.hasFriend(sone.getId());
+                               }
+                       });
+                       templateContext.set("followedSones", "hide");
+               }
+               if ("name".equals(sortField)) {
+                       if ("desc".equals(sortOrder)) {
+                               Collections.sort(knownSones, new ReverseComparator<Sone>(Sone.NICE_NAME_COMPARATOR));
+                       } else {
+                               Collections.sort(knownSones, Sone.NICE_NAME_COMPARATOR);
+                       }
+                       templateContext.set("sort", "name");
+                       templateContext.set("order", "desc".equals(sortOrder) ? "desc" : "asc");
+               } else if ("activity".equals(sortField)) {
+                       if ("asc".equals(sortOrder)) {
+                               Collections.sort(knownSones, new ReverseComparator<Sone>(Sone.LAST_ACTIVITY_COMPARATOR));
+                       } else {
+                               Collections.sort(knownSones, Sone.LAST_ACTIVITY_COMPARATOR);
+                       }
+                       templateContext.set("sort", "activity");
+                       templateContext.set("order", "asc".equals(sortOrder) ? "asc" : "desc");
+               }
                Pagination<Sone> sonePagination = new Pagination<Sone>(knownSones, 25).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("page"), 0));
                templateContext.set("pagination", sonePagination);
                templateContext.set("knownSones", sonePagination.getItems());
        }
-
 }
index 1dda47e..d38cea7 100644 (file)
@@ -680,3 +680,7 @@ textarea {
        color: red;
        font-style: italic;
 }
+
+#sone #sort-options {
+       margin-bottom: 1em;
+}
index 33f0e27..fde1060 100644 (file)
@@ -1,8 +1,52 @@
 <%include include/head.html>
 
        <div class="page-id hidden">known-sones</div>
+       
+       <script language="javascript">
+
+               $(document).ready(function() {
+                       $("select[name=sort]").change(function() {
+                               value = $(this).val();
+                               if (value == "activity") {
+                                       $("select[name=order]").val("desc");
+                               } else if (value == "name") {
+                                       $("select[name=order]").val("asc");
+                               } 
+                       });
+               });
+       
+       </script>
 
        <h1><%= Page.KnownSones.Page.Title|l10n|html></h1>
+       
+       <div id="sort-options">
+               <form action="knownSones.html" method="get">
+                       <div>
+                               Sort:
+                               <select name="sort">
+                                       <option value="name"<%if sort|match value="name"> selected="selected"<%/if>>Name</option>
+                                       <option value="activity"<%if sort|match value="activity"> selected="selected"<%/if>>Last activity</option>
+                               </select>
+                               <select name="order">
+                                       <option value="asc"<%if order|match value="asc"> selected="selected"<%/if>>Ascending</option>
+                                       <option value="desc"<%if order|match value="desc"> selected="selected"<%/if>>Descending</option>
+                               </select>
+                       </div>
+                       <%ifnull !currentSone>
+                               <div>
+                                       Followed Sones:
+                                       <select name="followedSones">
+                                               <option value="none"></option>
+                                               <option value="show-only"<%if followedSones|match value="show-only"> selected="selected"<%/if>>Show only followed Sones</option>
+                                               <option value="hide"<%if followedSones|match value="hide"> selected="selected"<%/if>>Hide followed Sones</option>
+                                       </select>
+                               </div>
+                       <%/if>
+                       <div>
+                               <button type="submit">Apply</button>
+                       </div>
+               </form>
+       </div>
 
        <div id="known-sones">
                <%= page|store key=pageParameter>