diff options
author | Vitaly Takmazov | 2016-12-28 22:38:21 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2017-01-10 12:08:35 +0300 |
commit | 2f682b5e3cfc3fc5f961b60129be7bc90e0d6a03 (patch) | |
tree | 840aea9eb94d5c1f667a710d3298135854bc5002 /juick-www/src/main/java/com/juick/www/controllers/UserThread.java | |
parent | eb440ea4f120115613880e340b010eed5397e72c (diff) |
juick-www: now on spring-webmvc
Diffstat (limited to 'juick-www/src/main/java/com/juick/www/controllers/UserThread.java')
-rw-r--r-- | juick-www/src/main/java/com/juick/www/controllers/UserThread.java | 374 |
1 files changed, 374 insertions, 0 deletions
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 new file mode 100644 index 00000000..4020e149 --- /dev/null +++ b/juick-www/src/main/java/com/juick/www/controllers/UserThread.java @@ -0,0 +1,374 @@ +/* + * Juick + * Copyright (C) 2008-2011, Ugnich Anton + * + * 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 <http://www.gnu.org/licenses/>. + */ +package com.juick.www.controllers; + +import com.juick.Message; +import com.juick.server.helpers.TagStats; +import com.juick.service.MessagesService; +import com.juick.service.TagService; +import com.juick.service.UserService; +import com.juick.util.MessageUtils; +import com.juick.www.WebApp; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import javax.inject.Inject; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author Ugnich Anton + */ +@Controller +public class UserThread { + + @Inject + WebApp webApp; + @Inject + MessagesService messagesService; + @Inject + UserService userService; + @Inject + TagService tagService; + @Inject + PageTemplates templates; + + @RequestMapping(value = "/{uname}/{mid}", method = RequestMethod.GET) + protected void doGetThread(HttpServletRequest request, HttpServletResponse response, + @PathVariable int mid) throws ServletException, IOException { + com.juick.User visitor = webApp.getVisitorUser(request, response); + + if (!messagesService.canViewThread(mid, visitor.getUid())) { + response.sendError(HttpServletResponse.SC_FORBIDDEN); + return; + } + + com.juick.Message msg = messagesService.getMessage(mid); + + boolean listview = false; + String paramView = request.getParameter("view"); + if (paramView != null) { + if (paramView.equals("list")) { + listview = true; + if (visitor.getUid() > 0) { + userService.setUserOptionInt(visitor.getUid(), "repliesview", 1); + } + } else if (paramView.equals("tree") && visitor.getUid() > 0) { + userService.setUserOptionInt(visitor.getUid(), "repliesview", 0); + } + } else if (visitor.getUid() > 0 && userService.getUserOptionInt(visitor.getUid(), "repliesview", 0) == 1) { + listview = true; + } + + String title = msg.getUser().getName() + ": " + msg.getTagsString(); + + response.setContentType("text/html; charset=UTF-8"); + try (PrintWriter out = response.getWriter()) { + String headers = "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"@" + msg.getUser().getName() + "\" href=\"//rss.juick.com/" + msg.getUser().getName() + "/blog\"/>"; + if (paramView != null) { + headers += "<link rel=\"canonical\" href=\"http://juick.com/" + msg.getUser().getName() + "/" + msg.getMid() + "\"/>"; + } + if (msg.Hidden) { + headers += "<meta name=\"robots\" content=\"noindex\"/>"; + } + templates.pageHead(out, visitor, title, headers); + templates.pageNavigation(out, visitor, null); + + out.println("<section id=\"content\" data-mid=\"" + msg.getMid() + "\" style=\"margin-left: 0; width: 100%\">"); + printMessage(out, msg, visitor); + printReplies(out, msg, visitor, listview); + out.println("</section>"); + + templates.pageFooter(request, out, visitor, false); + + templates.pageEnd(out); + } + } + + public com.juick.Message printMessage(PrintWriter out, com.juick.Message msg, com.juick.User visitor) { + msg.VisitorCanComment = visitor.getUid() > 0; + + List<TagStats> tags = tagService.getMessageTags(msg.getMid()); + String tagsStr = templates.formatTags(tags); + if (msg.ReadOnly) { + tagsStr += "<a>readonly</a>"; + msg.VisitorCanComment = false; + } + if (msg.getPrivacy() < 0) { + tagsStr += "<a>friends</a>"; + } + + 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 = "<div class=\"msg-tags\">" + tagsStr + "</div>"; + } + + out.println("<ul>"); + out.println(" <li id=\"msg-" + msg.getMid() + "\" data-mid=\"" + msg.getMid() + "\" class=\"msg msgthread\">"); + out.println(" <div class=\"msg-cont\">"); + out.println(" <div class=\"msg-menu\"><a href=\"#\"></a></div>"); + out.println(" <div class=\"msg-ts\">" + templates.formatJSLocalTime(msg.getDate()) + "</div>"); + out.println(" <div class=\"msg-avatar\"><a href=\"/" + msg.getUser().getName() + "/\"><img src=\"//i.juick.com/a/" + msg.getUser().getUid() + ".png\" alt=\"" + msg.getUser().getName() + "\"/></a></div>"); + out.println(" <div class=\"msg-header\">@<a href=\"/" + msg.getUser().getName() + "/\">" + msg.getUser().getName() + "</a>:" + tagsStr + "</div>"); + out.println(" <div class=\"msg-txt\">" + txt + "</div>"); + + if (msg.getAttachmentType() != null) { + out.println(" <div class=\"msg-media\"><a href=\"//i.juick.com/p/" + msg.getMid() + "." + msg.getAttachmentType() + "\"><img src=\"//i.juick.com/photos-512/" + msg.getMid() + "." + msg.getAttachmentType() + "\" alt=\"\"/></a></div>"); + } + + boolean visitorInBL = false; + if (visitor.getUid() > 0) { + if (visitor.getUid() == msg.getUser().getUid()) { + msg.VisitorCanComment = true; + } else { + visitorInBL = userService.isInBL(msg.getUser().getUid(), visitor.getUid()); + if (visitorInBL) { + msg.VisitorCanComment = false; + } + } + } + + if (msg.VisitorCanComment) { + out.println(" <form action=\"/comment\" method=\"POST\" enctype=\"multipart/form-data\"><input type=\"hidden\" name=\"mid\" value=\"" + msg.getMid() + "\"/>"); + out.println(" <div class=\"msg-comment\"><div class=\"ta-wrapper\"><textarea name=\"body\" rows=\"1\" class=\"reply\" placeholder=\"Написать комментарий\"></textarea></div></div>"); + out.println(" </form>"); + } + + List<String> recomm = messagesService.getMessageRecommendations(msg.getMid()); + if (!recomm.isEmpty()) { + out.print(" <div class=\"msg-recomms\">Рекомендовали (" + recomm.size() + "): "); + for (int i = 0; i < recomm.size(); i++) { + if (i > 0) { + out.print(", "); + } + out.print("<a href=\"/" + recomm.get(i) + "/\">@" + recomm.get(i) + "</a>"); + } + out.println("</div>"); + } + out.println(" </div>"); + out.println(" </li>"); + + out.println(" <li id=\"mtoolbar\"><ul>"); + out.println(" <li><a href=\"/" + msg.getMid() + "\"><div style=\"background-position: -64px 0\"></div>" + msg.getMid() + "</a></li>"); + if (visitor.getUid() > 0) { + if (visitor.getUid() != msg.getUser().getUid()) { + if (messagesService.isSubscribed(visitor.getUid(), msg.getMid())) { + out.println(" <li><a href=\"/post?body=U+%23" + msg.getMid() + "\"><div style=\"background-position: -48px 0\"></div>Подписан</a></li>"); + } else { + out.println(" <li><a href=\"/post?body=S+%23" + msg.getMid() + "\"><div style=\"background-position: -16px 0\"></div>Подписаться</a></li>"); + } + if (!visitorInBL) { + out.println(" <li><a href=\"/post?body=%21+%23" + msg.getMid() + "\"><div style=\"background-position: -32px 0\"></div>Рекомендовать</a></li>"); + } + } else { + out.println(" <li><a href=\"/post?body=D+%23" + msg.getMid() + "\"><div style=\"background-position: 0\"></div>Удалить</a></li>"); + } + } + out.println(" </ul></li>"); + out.println("</ul>"); + + return msg; + } + + public void printReplies(PrintWriter out, com.juick.Message msg, com.juick.User visitor, boolean listview) { + List<com.juick.Message> replies = messagesService.getReplies(msg.getMid()); + + List<Integer> blUIDs = new ArrayList<Integer>(); + 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())) { + blUIDs.add(reply.getUser().getUid()); + } + if (reply.getReplyto() > 0) { + boolean added = false; + for (int n = 0; n < replies.size(); n++) { + if (replies.get(n).getRid() == reply.getReplyto()) { + replies.get(n).childs.add(reply); + added = true; + break; + } + } + if (!added) { + reply.setReplyto(0); + } + } + } + + 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; + } + } + + boolean foldable = false; + if (replies.size() > 10) { + for (int i = 0; i < replies.size() - 1; i++) { + if (replies.get(i).getChildsCount() > 1) { + foldable = true; + break; + } + } + } + + out.println("<div class=\"title2\">"); + out.print(" <div class=\"title2-right\">"); + if (listview) { + out.print("<a href=\"?view=tree\" rel=\"nofollow\">Показать деревом</a>"); + } else { + if (foldable) { + out.print("<span id=\"unfoldall\"><a href=\"#\">Раскрыть все</a> · </span>"); + } + out.print("<a href=\"?view=list\" rel=\"nofollow\">Показать списком</a>"); + } + out.print("</div>"); + out.println(" <h2>Ответы (" + replies.size() + ")</h2>"); + out.println("</div>"); + + out.println("<ul id=\"replies\">"); + if (listview) { + printList(out, replies, visitor); + } else { + printTree(out, replies, visitor, 0, 0, false); + } + out.println("</ul>"); + + for (Message reply : replies) { + reply.cleanupChilds(); + } + replies.clear(); + } + } + + public void printTree(PrintWriter out, List<com.juick.Message> 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(" <li id=\"" + msg.getRid() + "\" class=\"msg\" style=\""); + if (margin > 0) { + out.print("margin-left: " + margin + "px;"); + } + if (hidden) { + out.print("display:none;"); + } + out.println("\">"); + out.println(" <div class=\"msg-cont\">"); + out.println(" <div class=\"msg-header\">"); + if (!msg.getUser().isBanned()) { + out.println(" @<a href=\"/" + msg.getUser().getName() + "/\">" + msg.getUser().getName() + "</a>:"); + out.println(" <div class=\"msg-avatar\"><a href=\"/" + msg.getUser().getName() + "/\"><img src=\"//i.juick.com/a/" + msg.getUser().getUid() + ".png\" alt=\"" + msg.getUser().getName() + "\"/></a></div>"); + } else { + out.println(" [удалено]:"); + out.println(" <div class=\"msg-avatar\"><img src=\"//i.juick.com/av-96.png\"/></div>"); + } + out.println(" <div class=\"msg-menu\"><a href=\"#\" class=\"a-thread-links\"></a></div>"); + out.println(" <div class=\"msg-ts\"><a href=\"/" + msg.getMid() + "#" + msg.getRid() + "\" title=\"" + templates.sdfSQL.format(msg.getDate()) + " GMT\">" + templates.formatDate(msg.TimeAgo, msg.getDate()) + "</a></div>"); + out.println(" </div>"); + out.println(" <div class=\"msg-txt\">" + MessageUtils.formatMessage(msg.getText()) + "</div>"); + if (msg.getAttachmentType() != null) { + out.println(" <div class=\"msg-media\"><a href=\"//i.juick.com/p/" + msg.getMid() + "-" + msg.getRid() + "." + msg.getAttachmentType() + "\"><img src=\"//i.juick.com/photos-512/" + msg.getMid() + "-" + msg.getRid() + "." + msg.getAttachmentType() + "\" alt=\"\"/></a></div>"); + } + out.print(" <div class=\"msg-links\">/" + msg.getRid()); + if (msg.getReplyto() > 0) { + out.print(" в ответ на <a href=\"#" + msg.getReplyto() + "\">/" + msg.getReplyto() + "</a>"); + } + if (msg.VisitorCanComment) { + out.println(" · <a href=\"/post?body=%23" + msg.getMid() + "/" + msg.getRid() + "%20\" class=\"a-thread-comment\">Ответить</a></div>"); + out.println(" <div class=\"msg-comment\" style=\"display: none\"></div>"); + } else if (visitor == null) { + out.println(" · <a href=\"#\" class=\"a-login\">Ответить</a></div>"); + } + + int childs = msg.getChildsCount(); + if (ReplyTo == 0 && childs > 1 && replies.size() > 10) { + out.println(" <div class=\"msg-comments\"><a href=\"#\">" + templates.formatReplies(childs) + "</a></div>"); + } + out.println(" </div>"); + out.println(" </li>"); + + 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<com.juick.Message> replies, com.juick.User visitor) { + for (Message msg : replies) { + out.print(" <li id=\"" + msg.getRid() + "\" class=\"msg\">"); + out.println(" <div class=\"msg-cont\">"); + out.println(" <div class=\"msg-header\">"); + if (!msg.getUser().isBanned()) { + out.println(" @<a href=\"/" + msg.getUser().getName() + "/\">" + msg.getUser().getName() + "</a>:"); + out.println(" <div class=\"msg-avatar\"><a href=\"/" + msg.getUser().getName() + "/\"><img src=\"//i.juick.com/a/" + msg.getUser().getUid() + ".png\" alt=\"" + msg.getUser().getName() + "\"/></a></div>"); + } else { + out.println(" [удалено]:"); + out.println(" <div class=\"msg-avatar\"><img src=\"//i.juick.com/av-96.png\"/></div>"); + } + out.println(" <div class=\"msg-menu\"><a href=\"#\" class=\"a-thread-links\"></a></div>"); + out.println(" <div class=\"msg-ts\"><a href=\"/" + msg.getMid() + "#" + msg.getRid() + "\" title=\"" + PageTemplates.sdfSQL.format(msg.getDate()) + " GMT\">" + templates.formatDate(msg.TimeAgo, msg.getDate()) + "</a></div>"); + out.println(" </div>"); + out.println(" <div class=\"msg-txt\">" + MessageUtils.formatMessage(msg.getText()) + "</div>"); + if (msg.getAttachmentType() != null) { + out.println(" <div class=\"msg-media\"><a href=\"//i.juick.com/p/" + msg.getMid() + "-" + msg.getRid() + "." + msg.getAttachmentType() + "\"><img src=\"//i.juick.com/photos-512/" + msg.getMid() + "-" + msg.getRid() + "." + msg.getAttachmentType() + "\" alt=\"\"/></a></div>"); + } + out.print(" <div class=\"msg-links\">/" + msg.getRid()); + if (msg.getReplyto() > 0) { + out.print(" в ответ на <a href=\"#" + msg.getReplyto() + "\">/" + msg.getReplyto() + "</a>"); + } + if (msg.VisitorCanComment) { + out.println(" · <a href=\"#\" class=\"a-thread-comment\">Ответить</a></div>"); + out.println(" <div class=\"msg-comment\" style=\"display: none\"></div>"); + } else if (visitor.getUid() == 0) { + out.println(" <div class=\"msg-links\"><a href=\"/post?body=%23" + msg.getMid() + "/" + msg.getRid() + "%20\" class=\"a-thread-comment\">Ответить</a></div>"); + } + out.println(" </div>"); + out.println(" </li>"); + } + } +} |