From f5a87d2b7072426cfe36527db1270e5f85b73e01 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Fri, 28 Jul 2017 14:21:01 +0300 Subject: user thread is on pebble now --- .../com/juick/www/controllers/PageTemplates.java | 7 - .../java/com/juick/www/controllers/UserThread.java | 318 +++------------------ .../pebble/extension/FormatterExtension.java | 2 + .../extension/filters/FormatRepliesFilter.java | 48 ++++ .../src/main/webapp/WEB-INF/layouts/content.html | 3 +- .../src/main/webapp/WEB-INF/views/macros/tree.html | 54 ++++ .../main/webapp/WEB-INF/views/partial/message.html | 6 +- .../webapp/WEB-INF/views/partial/thread_list.html | 44 +++ .../webapp/WEB-INF/views/partial/thread_tree.html | 2 + .../src/main/webapp/WEB-INF/views/thread.html | 108 +++++++ 10 files changed, 311 insertions(+), 281 deletions(-) create mode 100644 juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/FormatRepliesFilter.java create mode 100644 juick-www/src/main/webapp/WEB-INF/views/macros/tree.html create mode 100644 juick-www/src/main/webapp/WEB-INF/views/partial/thread_list.html create mode 100644 juick-www/src/main/webapp/WEB-INF/views/partial/thread_tree.html create mode 100644 juick-www/src/main/webapp/WEB-INF/views/thread.html (limited to 'juick-www/src/main') diff --git a/juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java b/juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java index f62b7678..a01cbc55 100644 --- a/juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java +++ b/juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java @@ -286,13 +286,6 @@ public class PageTemplates { } } - public String formatJSLocalTime(Date ts) { - return ""; - } - public String formatReplies(int replies) { int ld = replies % 10; int lh = replies % 100; diff --git a/juick-www/src/main/java/com/juick/www/controllers/UserThread.java b/juick-www/src/main/java/com/juick/www/controllers/UserThread.java index 543d52ad..9ab45333 100644 --- a/juick-www/src/main/java/com/juick/www/controllers/UserThread.java +++ b/juick-www/src/main/java/com/juick/www/controllers/UserThread.java @@ -17,7 +17,7 @@ package com.juick.www.controllers; import com.juick.Message; -import com.juick.server.helpers.TagStats; +import com.juick.server.util.HttpForbiddenException; import com.juick.server.util.HttpNotFoundException; import com.juick.service.MessagesService; import com.juick.service.TagService; @@ -28,11 +28,10 @@ import com.juick.www.WebApp; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.*; import javax.inject.Inject; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; @@ -57,14 +56,14 @@ public class UserThread { PageTemplates templates; @GetMapping("/{uname}/{mid}") - protected void doGetThread(HttpServletRequest request, HttpServletResponse response, - @PathVariable String uname, - @PathVariable int mid) throws IOException { + protected String threadAction(ModelMap model, + @PathVariable String uname, + @PathVariable int mid, + @RequestParam(required = false, value = "view") String paramView) throws IOException { com.juick.User visitor = UserUtils.getCurrentUser(); if (!messagesService.canViewThread(mid, visitor.getUid())) { - response.sendError(HttpServletResponse.SC_FORBIDDEN); - return; + throw new HttpForbiddenException(); } com.juick.Message msg = messagesService.getMessage(mid); @@ -75,12 +74,16 @@ public class UserThread { com.juick.User user = userService.getUserByName(uname); if (user.getUid() == 0 || !msg.getUser().equals(user)) { - response.sendRedirect(String.format("/%s/%d", msg.getUser().getName(), mid)); - return; + return String.format("redirect:/%s/%d", msg.getUser().getName(), mid); } + msg.VisitorCanComment = visitor.getUid() > 0; + if (visitor.getUid() > 0) { + msg.VisitorCanComment = visitor.getUid() == msg.getUser().getUid() + || !userService.isInBL(msg.getUser().getUid(), visitor.getUid()); + } + model.addAttribute("msg", msg); boolean listview = false; - String paramView = request.getParameter("view"); if (paramView != null) { if (paramView.equals("list")) { listview = true; @@ -93,136 +96,31 @@ public class UserThread { } else if (visitor.getUid() > 0 && userService.getUserOptionInt(visitor.getUid(), "repliesview", 0) == 1) { listview = true; } - + model.addAttribute("listview", listview); String title = msg.getUser().getName() + ": " + msg.getTagsString(); - response.setContentType("text/html; charset=UTF-8"); - try (PrintWriter out = response.getWriter()) { - String headers = ""; - if (paramView != null) { - headers += ""; - } - if (msg.Hidden) { - headers += ""; - } - templates.pageHead(out, visitor, title, headers); - templates.pageNavigation(out, visitor, null); - - out.println("
"); - printMessage(out, msg, visitor); - printReplies(out, msg, visitor, listview); - out.println("
"); - - templates.pageFooter(request, out, visitor, visitor.getUid() == 0); - - templates.pageEnd(out); - } - } - - // when message id is not fit to int - @ExceptionHandler(NumberFormatException.class) - public ResponseEntity notfound() { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } - - public com.juick.Message printMessage(PrintWriter out, com.juick.Message msg, com.juick.User visitor) { - msg.VisitorCanComment = visitor.getUid() > 0; - - List tags = tagService.getMessageTags(msg.getMid()); - String tagsStr = templates.formatTags(tags); - if (msg.ReadOnly) { - tagsStr += "readonly"; - msg.VisitorCanComment = false; - } - if (msg.getPrivacy() < 0) { - tagsStr += "friends"; - } - - String txt; - if (msg.getTags().stream().anyMatch(t -> t.getName().equals("code"))) { - txt = MessageUtils.formatMessageCode(msg.getText()); - } else { - txt = MessageUtils.formatMessage(msg.getText()); - } - - if (!tags.isEmpty()) { - tagsStr = "
" + tagsStr + "
"; - } - - out.println(""); - - return msg; - } - - public void printReplies(PrintWriter out, com.juick.Message msg, com.juick.User visitor, boolean listview) { + model.addAttribute("headers", headers); + model.addAttribute("contentStyle", "margin-left: 0; width: 100%"); + model.addAttribute("isModerator", visitor.getUid() == 3694); + model.addAttribute("visitorSubscribed", messagesService.isSubscribed(visitor.getUid(), msg.getMid())); + model.addAttribute("visitorInBL", userService.isInBL(msg.getUser().getUid(), visitor.getUid())); + model.addAttribute("recomm", messagesService.getMessageRecommendations(msg.getMid())); List replies = messagesService.getReplies(msg.getMid()); - List blUIDs = new ArrayList(); + List blUIDs = new ArrayList<>(); for (int i = 0; i < replies.size(); i++) { com.juick.Message reply = replies.get(i); - if (reply.getUser().getUid() != msg.getUser().getUid() && !blUIDs.contains(reply.getUser().getUid())) { + if (reply.getUser().getUid() != msg.getUser().getUid() + && !blUIDs.contains(reply.getUser().getUid())) { blUIDs.add(reply.getUser().getUid()); } if (reply.getReplyto() > 0) { @@ -238,6 +136,15 @@ public class UserThread { reply.setReplyto(0); } } + if (visitor.getUid() > 0 && msg.getUser().getUid() == visitor.getUid()) { + reply.VisitorCanComment = true; + } else if (visitor.getUid() > 0 && msg.VisitorCanComment) { + List blUIDs2 = userService.checkBL(visitor.getUid(), blUIDs); + reply.VisitorCanComment = reply.getUser().getUid() == visitor.getUid() + || !blUIDs2.contains(reply.getUser().getUid()); + } else { + reply.VisitorCanComment = false; + } } boolean foldable = false; @@ -249,145 +156,14 @@ public class UserThread { } } } - - out.println("
"); - out.print("
"); - if (listview) { - out.print("Показать деревом"); - } else { - if (foldable) { - out.print("Раскрыть все · "); - } - out.print("Показать списком"); - } - out.print("
"); - out.println("

Ответы (" + replies.size() + ")

"); - out.println("
"); - - out.println("
    "); - - if (!replies.isEmpty()) { - if (visitor.getUid() > 0 && msg.getUser().getUid() == visitor.getUid()) { - for (Message reply : replies) { - reply.VisitorCanComment = true; - } - } else if (visitor.getUid() > 0 && msg.VisitorCanComment) { - blUIDs = userService.checkBL(visitor.getUid(), blUIDs); - for (Message reply : replies) { - reply.VisitorCanComment = reply.getUser().getUid() == visitor.getUid() || !blUIDs.contains(reply.getUser().getUid()); - } - } else { - for (Message reply : replies) { - reply.VisitorCanComment = false; - } - } - - if (listview) { - printList(out, replies, visitor); - } else { - printTree(out, replies, visitor, 0, 0, false); - } - - for (Message reply : replies) { - reply.cleanupChilds(); - } - replies.clear(); - } - - out.println("
"); + model.addAttribute("replies", replies); + model.addAttribute("foldable", foldable); + return "views/thread"; } - public void printTree(PrintWriter out, List replies, com.juick.User visitor, int ReplyTo, int margin, boolean hidden) { - if (margin > 240) { - margin = 240; - } - - for (int i = 0; i < replies.size(); i++) { - com.juick.Message msg = replies.get(i); - if (msg.getReplyto() == ReplyTo) { - - out.print("
  • 0) { - out.print("margin-left: " + margin + "px;"); - } - if (hidden) { - out.print("display:none;"); - } - out.println("\">"); - out.println("
    "); - out.println("
    "); - if (!msg.getUser().isBanned()) { - out.println(" @" + msg.getUser().getName() + ":"); - out.println("
    \""
    "); - } else { - out.println(" [удалено]:"); - out.println("
    "); - } - out.println("
    "); - out.println(" "); - out.println("
    "); - out.println("
    " + MessageUtils.formatMessage(msg.getText()) + "
    "); - if (msg.getAttachmentType() != null) { - out.println("
    \"\"/
    "); - } - out.print("
    /" + msg.getRid()); - if (msg.getReplyto() > 0) { - out.print(" в ответ на /" + msg.getReplyto() + ""); - } - if (msg.VisitorCanComment) { - out.println(" · Ответить
    "); - out.println("
    "); - } else if (visitor.getUid() == 0) { - out.println(" · Ответить
    "); - } - - int childs = msg.getChildsCount(); - if (ReplyTo == 0 && childs > 1 && replies.size() > 10) { - out.println(" "); - } - out.println(" "); - out.println("
  • "); - - if (ReplyTo == 0 && childs > 1 && replies.size() > 10) { - printTree(out, msg.childs, visitor, msg.getRid(), margin + 20, true); - } else if (childs > 0) { - printTree(out, msg.childs, visitor, msg.getRid(), margin + 20, hidden); - } - } - } - } - - public void printList(PrintWriter out, List replies, com.juick.User visitor) { - for (Message msg : replies) { - out.print("
  • "); - out.println("
    "); - out.println("
    "); - if (!msg.getUser().isBanned()) { - out.println(" @" + msg.getUser().getName() + ":"); - out.println("
    \""
    "); - } else { - out.println(" [удалено]:"); - out.println("
    "); - } - out.println("
    "); - out.println(" "); - out.println("
    "); - out.println("
    " + MessageUtils.formatMessage(msg.getText()) + "
    "); - if (msg.getAttachmentType() != null) { - out.println("
    \"\"/
    "); - } - out.print("
    /" + msg.getRid()); - if (msg.getReplyto() > 0) { - out.print(" в ответ на /" + msg.getReplyto() + ""); - } - if (msg.VisitorCanComment) { - out.println(" · Ответить
    "); - out.println("
    "); - } else if (visitor.getUid() == 0) { - out.println(" "); - } - out.println("
    "); - out.println("
  • "); - } + // when message id is not fit to int + @ExceptionHandler(NumberFormatException.class) + public ResponseEntity notFoundAction() { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); } } diff --git a/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/FormatterExtension.java b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/FormatterExtension.java index 01b63b0a..7702a316 100644 --- a/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/FormatterExtension.java +++ b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/FormatterExtension.java @@ -18,6 +18,7 @@ package com.mitchellbosecke.pebble.extension; import com.mitchellbosecke.pebble.extension.filters.FormatMessageFilter; +import com.mitchellbosecke.pebble.extension.filters.FormatRepliesFilter; import com.mitchellbosecke.pebble.extension.filters.PrettyTimeFilter; import com.mitchellbosecke.pebble.extension.filters.TagsListFilter; @@ -32,6 +33,7 @@ public class FormatterExtension extends AbstractExtension { public Map getFilters() { Map filters = new HashMap<>(); filters.put("formatMessage", new FormatMessageFilter()); + filters.put("formatReplies", new FormatRepliesFilter()); filters.put("prettyTime", new PrettyTimeFilter()); filters.put("tagsList", new TagsListFilter()); return filters; diff --git a/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/FormatRepliesFilter.java b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/FormatRepliesFilter.java new file mode 100644 index 00000000..f375ecdb --- /dev/null +++ b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/FormatRepliesFilter.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2017, Juick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.mitchellbosecke.pebble.extension.filters; + +import com.juick.Message; +import com.mitchellbosecke.pebble.extension.Filter; + +import java.util.List; +import java.util.Map; + +public class FormatRepliesFilter implements Filter { + @Override + public Object apply(Object input, Map args) { + if (input instanceof Message) { + int replies = ((Message)input).getChildsCount(); + int ld = replies % 10; + int lh = replies % 100; + if ((lh < 10 || lh > 20) && ld == 1) { + return replies + " ответ"; + } else if ((lh < 10 || lh > 20) && ld > 1 && ld < 5) { + return replies + " ответа"; + } else { + return replies + " ответов"; + } + } + throw new IllegalArgumentException("invalid input"); + } + + @Override + public List getArgumentNames() { + return null; + } +} diff --git a/juick-www/src/main/webapp/WEB-INF/layouts/content.html b/juick-www/src/main/webapp/WEB-INF/layouts/content.html index 420d4e0c..c059678e 100644 --- a/juick-www/src/main/webapp/WEB-INF/layouts/content.html +++ b/juick-www/src/main/webapp/WEB-INF/layouts/content.html @@ -31,7 +31,8 @@ {% include "views/partial/navigation" %} -
    +
    {% block content %} {% endblock %}
    diff --git a/juick-www/src/main/webapp/WEB-INF/views/macros/tree.html b/juick-www/src/main/webapp/WEB-INF/views/macros/tree.html new file mode 100644 index 00000000..3e35f92a --- /dev/null +++ b/juick-www/src/main/webapp/WEB-INF/views/macros/tree.html @@ -0,0 +1,54 @@ +{% macro tree(replies, visitor, level, margin, hidden) %} +{% for msg in replies %} + {% if msg.replyto == level %} +
  • +
    +
    +{% if not msg.user.banned %} + @{{ msg.user.name }}: +
    + {{ msg.user.name }} +
    +{% else %} + [удалено]: +
    + +
    +{% endif %} +
    + +
    + +
    +
    {{ msg | formatMessage }}
    +
    + + +{% elseif visitor.uid == 0 %} + ·
    +{% endif %} + +{% if level == 0 and msg.childsCount > 1 and replies.size() > 10 %} + +{% endif %} +
  • + {% if (level == 0 and msg.childsCount > 1 and replies.size() > 10) %} + {{ tree(msg.childs, visitor, msg.rid, margin + 20, true) }} + {% elseif (msg.childsCount > 0) %} + {{ tree(msg.childs, visitor, msg.rid, margin + 20, hidden) }} + {% endif %} + {% endif %} +{% endfor %} +{% endmacro %} \ No newline at end of file diff --git a/juick-www/src/main/webapp/WEB-INF/views/partial/message.html b/juick-www/src/main/webapp/WEB-INF/views/partial/message.html index cdfad6b6..f67362ce 100644 --- a/juick-www/src/main/webapp/WEB-INF/views/partial/message.html +++ b/juick-www/src/main/webapp/WEB-INF/views/partial/message.html @@ -1,7 +1,9 @@
    -
    @{{ msg.user.name }}: +
    + @{{ msg.user.name }}: + {{ msg.user.name }} +
    + + +{% endfor %} \ No newline at end of file diff --git a/juick-www/src/main/webapp/WEB-INF/views/partial/thread_tree.html b/juick-www/src/main/webapp/WEB-INF/views/partial/thread_tree.html new file mode 100644 index 00000000..f207b8e0 --- /dev/null +++ b/juick-www/src/main/webapp/WEB-INF/views/partial/thread_tree.html @@ -0,0 +1,2 @@ +{% import "views/macros/tree" %} +{{ tree(replies, visitor, 0, 0, false) }} \ No newline at end of file diff --git a/juick-www/src/main/webapp/WEB-INF/views/thread.html b/juick-www/src/main/webapp/WEB-INF/views/thread.html new file mode 100644 index 00000000..301ad8f8 --- /dev/null +++ b/juick-www/src/main/webapp/WEB-INF/views/thread.html @@ -0,0 +1,108 @@ +{% extends "layouts/content" %} +{% import "views/macros/tags" %} +{% block content %} + +
    +
    + {% if listview %} + Показать деревом + {% else %} + {% if foldable %} + Раскрыть все · + {% endif %} + Показать списком + {% endif %} +
    +

    Ответы ({{ replies.size() }})

    +
    + +
      + {% if (listview) %} + {% include "views/partial/thread_list" %} + {% else %} + {% include "views/partial/thread_tree" %} + {% endif %} +
    +{% endblock %} +{% block "column" %} +{% endblock %} \ No newline at end of file -- cgit v1.2.3