aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2016-12-09 17:35:49 +0300
committerGravatar Vitaly Takmazov2016-12-09 17:35:49 +0300
commite2a018e998e125ee2ec983962059c4d2b733a4b4 (patch)
tree2366ed5a465107c7acd539d22610462204f272c3
parent87d82a83c604b81abef8766a84f1c8b6f99add59 (diff)
juick-spring-www: WIP
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/WebApp.java79
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/configuration/WebAppConfiguration.java5
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/controllers/LoginController.java65
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/controllers/PMController.java138
-rw-r--r--juick-spring-www/src/main/webapp/WEB-INF/templates/views/login.html139
-rw-r--r--juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/footer.html8
-rw-r--r--juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/homecolumn.html6
-rw-r--r--juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/navigation.html45
-rw-r--r--juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_inbox.html44
-rw-r--r--juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_sent.html42
-rw-r--r--juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_about.html8
11 files changed, 544 insertions, 35 deletions
diff --git a/juick-spring-www/src/main/java/com/juick/www/WebApp.java b/juick-spring-www/src/main/java/com/juick/www/WebApp.java
new file mode 100644
index 00000000..6b26ec03
--- /dev/null
+++ b/juick-spring-www/src/main/java/com/juick/www/WebApp.java
@@ -0,0 +1,79 @@
+package com.juick.www;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.env.Environment;
+import rocks.xmpp.core.XmppException;
+import rocks.xmpp.core.session.Extension;
+import rocks.xmpp.core.session.XmppSessionConfiguration;
+import rocks.xmpp.extensions.component.accept.ExternalComponent;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * Created by vitalyster on 09.12.2016.
+ */
+public class WebApp implements AutoCloseable {
+ private static Logger logger = LoggerFactory.getLogger(WebApp.class);
+
+ private ExternalComponent xmpp;
+
+ public String tmpDir;
+ public String imgDir;
+
+ private String xmppHost, xmppPassword, xmppJid;
+ private int xmppPort;
+ private boolean isXmppDisabled;
+
+
+ public WebApp(Environment conf) {
+ tmpDir = conf.getProperty("upload_tmp_dir", "/var/www/juick.com/i/tmp/");
+ imgDir = conf.getProperty("img_path", "/var/www/juick.com/i/");
+ isXmppDisabled = BooleanUtils.toBoolean(conf.getProperty("xmpp_disabled"));
+ xmppHost = conf.getProperty("xmpp_host", "localhost");
+ xmppPort = NumberUtils.toInt(conf.getProperty("xmpp_port", "5347"), 5347);
+ xmppJid = conf.getProperty("xmpp_jid", "www.localhost");
+ xmppPassword = conf.getProperty("xmpp_password");
+ }
+
+ @PostConstruct
+ public void init() {
+ if (!isXmppDisabled) {
+ setupXmppComponent(xmppHost, xmppPort, xmppJid, xmppPassword);
+ }
+ }
+
+ @Override
+ public void close() {
+ try {
+ if (getXmpp() != null)
+ getXmpp().close();
+
+ logger.info("ExternalComponent on juick-www destroyed");
+ } catch (Exception e) {
+ logger.warn("Exception occurs on juick-www destroy", e);
+ }
+ }
+
+ public void setupXmppComponent(final String host, final int port, final String jid, final String password) {
+ XmppSessionConfiguration configuration = XmppSessionConfiguration.builder()
+ .extensions(Extension.of(com.juick.Message.class))
+ .build();
+ setXmpp(ExternalComponent.create(jid, password, configuration, host, port));
+ try {
+ getXmpp().connect();
+ } catch (XmppException e) {
+ logger.warn("xmpp extension", e);
+ }
+ }
+
+ public ExternalComponent getXmpp() {
+ return xmpp;
+ }
+
+ public void setXmpp(ExternalComponent xmpp) {
+ this.xmpp = xmpp;
+ }
+}
diff --git a/juick-spring-www/src/main/java/com/juick/www/configuration/WebAppConfiguration.java b/juick-spring-www/src/main/java/com/juick/www/configuration/WebAppConfiguration.java
index 5fb7848d..eaed8ebd 100644
--- a/juick-spring-www/src/main/java/com/juick/www/configuration/WebAppConfiguration.java
+++ b/juick-spring-www/src/main/java/com/juick/www/configuration/WebAppConfiguration.java
@@ -1,5 +1,6 @@
package com.juick.www.configuration;
+import com.juick.www.WebApp;
import com.juick.www.settings.TemplateSettingsHolder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -34,4 +35,8 @@ public class WebAppConfiguration {
public TemplateSettingsHolder settingsHolder() {
return new TemplateSettingsHolder(env);
}
+ @Bean
+ public WebApp webApp() {
+ return new WebApp(env);
+ }
}
diff --git a/juick-spring-www/src/main/java/com/juick/www/controllers/LoginController.java b/juick-spring-www/src/main/java/com/juick/www/controllers/LoginController.java
new file mode 100644
index 00000000..8a474c9b
--- /dev/null
+++ b/juick-spring-www/src/main/java/com/juick/www/controllers/LoginController.java
@@ -0,0 +1,65 @@
+package com.juick.www.controllers;
+
+import com.juick.User;
+import com.juick.server.util.HttpBadRequestException;
+import com.juick.server.util.HttpForbiddenException;
+import com.juick.service.UserService;
+import com.juick.util.UserUtils;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.inject.Inject;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import java.net.URI;
+import java.security.Principal;
+import java.util.Optional;
+
+/**
+ * Created by vitalyster on 09.12.2016.
+ */
+@Controller
+public class LoginController {
+ @Inject
+ UserService userService;
+ @Inject
+ Environment env;
+
+ @RequestMapping(value = "/login", method = RequestMethod.GET)
+ public String doGetLoginForm(Principal principal) {
+ String name = UserUtils.getUsername(principal, null);
+ User visitor = userService.getUserByName(name);
+ if (visitor.getUid() > 0) {
+ return "redirect:/login";
+ }
+ return "views/login";
+ }
+ @RequestMapping(value = "/login", method = RequestMethod.POST)
+ protected String doPostLogin(
+ @RequestParam("username") Optional<String> username,
+ @RequestParam("password") Optional<String> password,
+ @RequestHeader("Referer") Optional<String> referer,
+ HttpServletResponse response) {
+ if (!username.isPresent() && password.isPresent()) {
+ throw new HttpBadRequestException();
+ }
+
+ int uid = userService.checkPassword(username.get(), password.get());
+ if (uid > 0) {
+ if (referer.isPresent()) {
+ URI refererURI = URI.create(referer.get());
+ if (refererURI.getHost().equals(env.getProperty("web_domain"))
+ && !refererURI.getPath().equals("/login")) {
+ return "redirect:" + referer.get();
+ } else {
+ return "redirect:/";
+ }
+ }
+ }
+ throw new HttpForbiddenException();
+ }
+}
diff --git a/juick-spring-www/src/main/java/com/juick/www/controllers/PMController.java b/juick-spring-www/src/main/java/com/juick/www/controllers/PMController.java
new file mode 100644
index 00000000..c3b37cf6
--- /dev/null
+++ b/juick-spring-www/src/main/java/com/juick/www/controllers/PMController.java
@@ -0,0 +1,138 @@
+package com.juick.www.controllers;
+
+import com.juick.Message;
+import com.juick.User;
+import com.juick.server.util.HttpBadRequestException;
+import com.juick.server.util.HttpForbiddenException;
+import com.juick.service.PMQueriesService;
+import com.juick.service.TagService;
+import com.juick.service.UserService;
+import com.juick.util.MessageUtils;
+import com.juick.util.UserUtils;
+import com.juick.www.WebApp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import rocks.xmpp.addr.Jid;
+
+import javax.inject.Inject;
+import java.security.Principal;
+import java.util.List;
+
+/**
+ * Created by vitalyster on 09.12.2016.
+ */
+@Controller
+public class PMController {
+
+ private static final Logger logger = LoggerFactory.getLogger(PMController.class);
+
+ @Inject
+ PMQueriesService pmQueriesService;
+ @Inject
+ UserService userService;
+ @Inject
+ TagService tagService;
+ @Inject
+ WebApp webApp;
+
+ @RequestMapping("/pm/inbox")
+ public String doGetInbox(Principal principal, ModelMap context) {
+ String name = UserUtils.getUsername(principal, null);
+ User visitor = userService.getUserByName(name);
+ String title = "PM: Inbox";
+ List<Message> msgs = pmQueriesService.getLastPMInbox(visitor.getUid());
+ msgs.forEach(m -> m.setText(MessageUtils.formatMessage(m.getText())));
+ context.put("title", title);
+ context.put("visitor", visitor);
+ context.put("msgs", msgs);
+ context.put("tags", tagService.getPopularTags());
+ return "views/pm_inbox";
+ }
+
+ @RequestMapping(value = "/pm/sent", method = RequestMethod.GET)
+ public String doGetSent(
+ Principal principal,
+ @RequestParam String uname,
+ ModelMap context) {
+ String title = "PM: Sent";
+ String name = UserUtils.getUsername(principal, null);
+ User visitor = userService.getUserByName(name);
+ List<com.juick.Message> msgs = pmQueriesService.getLastPMSent(visitor.getUid());
+
+ if (!UserUtils.checkUserNameValid(uname)) {
+ uname = "";
+ }
+ context.put("title", title);
+ context.put("visitor", visitor);
+ context.put("msgs", msgs);
+ context.put("tags", tagService.getPopularTags());
+ context.put("uname", uname);
+ return "views/pm_sent";
+ }
+
+ @RequestMapping(value = "/pm/sent", method = RequestMethod.POST)
+ public String doPostPM(
+ Principal principal,
+ @RequestParam String uname,
+ @RequestParam String body,
+ ModelMap context) {
+ String name = UserUtils.getUsername(principal, null);
+ User visitor = userService.getUserByName(name);
+ if (uname.startsWith("@")) {
+ uname = uname.substring(1);
+ }
+ int uid = 0;
+ if (UserUtils.checkUserNameValid(uname)) {
+ uid = userService.getUIDbyName(uname);
+ }
+
+ if (uid == 0 || body == null || body.length() < 1 || body.length() > 10240) {
+ throw new HttpBadRequestException();
+ }
+
+ if (userService.isInBLAny(uid, visitor.getUid())) {
+ throw new HttpForbiddenException();
+ }
+
+ if (pmQueriesService.createPM(visitor.getUid(), uid, body)) {
+ if (webApp.getXmpp() != null) {
+ rocks.xmpp.core.stanza.model.Message msg = new rocks.xmpp.core.stanza.model.Message();
+ msg.setFrom(Jid.of("juick@juick.com"));
+ msg.setTo(Jid.of(String.format("%d@push.juick.com", uid)));
+ com.juick.Message jmsg = new com.juick.Message();
+ jmsg.setUser(visitor);
+ jmsg.setText(body);
+ msg.addExtension(jmsg);
+ webApp.getXmpp().send(msg);
+
+ msg.setTo(Jid.of(String.format("%d@ws.juick.com", uid)));
+ webApp.getXmpp().send(msg);
+
+ List<String> jids = userService.getJIDsbyUID(uid);
+ for (String jid : jids) {
+ rocks.xmpp.core.stanza.model.Message mm = new rocks.xmpp.core.stanza.model.Message();
+ mm.setTo(Jid.of(jid));
+ mm.setType(rocks.xmpp.core.stanza.model.Message.Type.CHAT);
+ if (pmQueriesService.havePMinRoster(visitor.getUid(), jid)) {
+ mm.setFrom(Jid.of(jmsg.getUser().getName(), "juick.com", "Juick"));
+ mm.setBody(body);
+ } else {
+ mm.setFrom(Jid.of("juick", "juick.com", "Juick"));
+ mm.setBody("Private message from @" + jmsg.getUser().getName() + ":\n" + body);
+ }
+ webApp.getXmpp().send(mm);
+ }
+ } else {
+ logger.warn("XMPP unavailable");
+ }
+ return "redirect:/pm/sent";
+ } else {
+ throw new HttpBadRequestException();
+ }
+ }
+}
diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/login.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/login.html
new file mode 100644
index 00000000..ae3aede6
--- /dev/null
+++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/login.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Juick</title>
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" defer="defer"></script>
+ <style>
+ * { margin: 0; padding: 0; }
+ html { font-family: sans-serif; }
+ html { background: #eeeee5; }
+ body { margin: 100px auto 0 auto; width: 1000px; }
+ a { color: #069; }
+ ul { float: left; width: 700px; height: 350px; list-style-type: none; background: url(/tagscloud.png) no-repeat; position: relative; }
+ ul a { position: absolute; display: block; text-indent: 100%; white-space: nowrap; overflow: hidden; }
+
+ #bottom1 { position: absolute; left: 0px; bottom: 10px; width: 100%; text-align: center; color: #555; }
+ #bottom2 { position: absolute; left: 0px; bottom: -50px; width: 100%; padding-bottom: 20px; text-align: center; font-size: small; color: #777; }
+
+ #signup,#signin { margin-left: 730px; width: 250px; }
+ #signup { padding-top: 25px; }
+ #signup>div { width: 100%; margin: 15px 0; }
+ #signup>div>a { display: block; width: 100%; height: 32px; line-height: 32px; text-indent: 37px; text-decoration: none; overflow: hidden; }
+
+ #facebook a { color: #FFF; background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c6QAAADNQTFRFO1edX3ewl6bLnKrOoK3QrrrYvMXe2N7r3OLu3+Tv5urz7O/29vf6+Pn7+vv9/Pz9////ykQjsQAAAEZJREFUOMtjYBgFuAATO68ADxdOaUYuATDAqYBbAL8CFgECCjiBcqz4XMiPz3oQEKCtAgEkwEdIAQchBWyEFDAPkDdHsAIAhZkIwz/VK/UAAAAASUVORK5CYII=") no-repeat #3A569C; }
+ #vk a { color: #FFF; background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c6QAAAHJQTFRFbY+zbo+zbpCzb5C0cpO1c5O2dZW3dpa4e5m6gJ29gZ69lq/In7bNo7jPrcDUs8XXvs3dv87dy9fkztnlz9rm0Nrm093o1N7o1+Dq3OTt3ubu4Ofv5Orw7fH27vL28PP38vX49Pb5+vv8+/z9/Pz9////2jSYlQAAAG5JREFUOMvtkEcOgDAMBE3vvXdIyP+/iMMRKfYHmMtcRtE6AD8f1Is8pyKgAs0RGYO2HSWqMQaoBHVRgYsS3AsrtyFlrqgdJlCLb95gxQO6IkZCqL+KCjz0TQU5ejOf2a3aJXPF7BOB2PvMhp8PDzGRFgEe7xvEAAAAAElFTkSuQmCC") no-repeat #6d8fb3; }
+ #xmpp>a { color: #333; background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c6QAAAt9QTFRFBj5rCUFoFz5mDEFuDUNqGUJkGUNgAEprEkVtGkRhHURnHEZjAE+BIElmEEx/HEx0PUdTHE5wMEtfO0laJk5sFlN6Nk1cKFBuIlJ1R0pYRExTGF2KMVh1OFhxDGSQT1deNlx6TVhkIGKPUlphKWOFU1tiOmB+Vl1kmlAuNmaDQGpaIG6ba2Q2SGeBN2uUNW+LF3mGRmyLV3BAL3xWgmVJ2VAa2lEb0VYX11UafWlmam9mam5xy1km3lUea29y2VccvF8obHBz21gd4VcXS3ebPoVG1lwl5FkaU3iYYHaH2F0ejHFIx2Iv4V0aP4o+02As218g4l4bPYtFX351KZFaymU43mIrVYoz5mEfT4w0xGsrSo82eXqDw2s+z2k1OZVAT4SoPZU5RZM4NJVYbYc8VoSiWY43WItbuXBK52gYOI20TpM6YYSYfX98T5Q7foB9aYSZSZc8Ro21cYxH7GwdT46e0HFGeopO2HA8V5ZEf4s8528l1HM7UJs5UI+xXoyrWZhGY4ylyHdMwXhXQZS7XpdNU5tH4XJBYJZZcIuhbpJk0HdPU588kohqOZ2pVZS30XpX6XcxSaFrz4FIUqVWWqVCYZm23YBGxYRrZZ2QXpy/5YFC7IA+6oBRb6ZUcKZn44ZSgKJu54hHmJqXbbBNfKh3cq5nYqrMpJyVdrBjx5WCo56diamAjaWdyZeE8JFV8ZJWnqOlaK/Sd7Zh7pVdgbN6x52N8JdfwqCU8ZhgZLbXb7a5grtTmK+UxKKWtqahq6qhd7bHqauop6yvqqyp755pbbzRrK6rwamgib53qq+xra+sobSg86Jza8PJsLKujMVctrGwqLapv7Crr7Wr8ad1srSxj8R9uLOys7WyubSztLazkcZ/sre6tbe0r7m0tri1t7m2vri3uLq3v7m4ubu4nc9mpNBvos2UptJxtNWXtteFuNmbuNyQud2Rut6SwN+aweCbwuGdw+KeweKkF4OfHQAAAadJREFUOMtjeEoAMAwfBQ9vYJO68RCu4BYDq1bXmr2XHoMlnlzet2qGpTgX8y2EFWwensEdrW2FbUAlJ2zDKsqaYwo6eZHcIGzoor/s5IdPSfefPt3nf3Xn3HZpPU8xJAXWIvU88VOffcm78vTptrijJe4OfAmy1kgKzjMlaIfUPvvQcObp03U120ucTZQaGc8je1NZrd8g8cL7eUufPp0wfX2mvVydripKONzkTG1JXvL6TuXTR/Zb5gR6F+Vw30QNqNUss/pqn3/MvrTD7Wy1V9Y0jtXoIZnLv2nSnrfzF3bP3hDRu1wwHzOo1VWOTXn5yi/q7MTJuxTUscTFQyHNc5vfbU1btOCgjNBDbJH1UF5i9/XP6VVrJRUfYo/Nx3YcpS/euOo4Pn6MqeDx44f3LoY2SYnOXBlUfPPug8cwRQxQ6Qf39sda+HqZaQiwGydFlx+4eQ+qAqrg4b3bPqbmNhkrNm5cbGUUHply7d6Dh8hWPH744Oa186eOHDl06NDh46fP33zwEMUEiCMe3L13GwjuPbj38PHTx9jT5OPHj5G9MFQyDgA8riWAv9eLFAAAAABJRU5ErkJggg==") no-repeat #BBB; }
+ #xmppinfo { background: #FFF; padding: 10px; display: none; }
+
+ #signin { text-align: center; font-size: small; }
+ #signinform { background: #FFF; padding: 10px 15px; margin-top: 15px; display: none; }
+ input.txt { width: 212px; border: 1px solid #CCC; margin: 3px 0; padding: 3px; }
+ input.submit { width: 70px; border: 1px solid #CCC; margin: 3px 0; padding: 3px; }
+ </style>
+ <link rel="icon" href="//i.juick.com/favicon.png"/>
+</head>
+
+<body>
+
+<ul id="tags">
+ <li><a href="/tag/juick" style="left: 359px; top: 120px; width: 311px; height: 99px">juick</a></li>
+ <li><a href="/tag/linux" style="left: 201px; top: 100px; width: 98px; height: 35px">linux</a></li>
+ <li><a href="/tag/android" style="left: 314px; top: 42px; width: 45px; height: 158px">android</a></li>
+ <li><a href="/tag/работа" style="left: 149px; top: 138px; width: 165px; height: 41px">работа</a></li>
+ <li><a href="/tag/music" style="left: 119px; top: 249px; width: 124px; height: 32px">music</a></li>
+ <li><a href="/tag/windows" style="left: 448px; top: 234px; width: 186px; height: 32px">windows</a></li>
+ <li><a href="/tag/google" style="left: 244px; top: 252px; width: 134px; height: 41px">google</a></li>
+ <li><a href="/tag/кино" style="left: 68px; top: 83px; width: 97px; height: 28px">кино</a></li>
+ <li><a href="/tag/фото" style="left: 400px; top: 266px; width: 101px; height: 29px">фото</a></li>
+ <li><a href="/tag/жизнь" style="left: 554px; top: 266px; width: 125px; height: 27px">жизнь</a></li>
+ <li><a href="/tag/еда" style="left: 46px; top: 196px; width: 71px; height: 32px">еда</a></li>
+ <li><a href="/tag/музыка" style="left: 61px; top: 111px; width: 139px; height: 27px">музыка</a></li>
+ <li><a href="/tag/прекрасное" style="left: 152px; top: 200px; width: 205px; height: 32px">прекрасное</a></li>
+ <li><a href="/tag/книги" style="left: 148px; top: 293px; width: 103px; height: 25px">книги</a></li>
+ <li><a href="/tag/цитата" style="left: 325px; top: 301px; width: 126px; height: 27px">цитата</a></li> <li><a href="/tag/games" style="left: 117px; top: 142px; width: 30px; height: 104px">games</a></li>
+ <li><a href="/tag/ubuntu" style="left: 503px; top: 2px; width: 28px; height: 102px">ubuntu</a></li>
+ <li><a href="/tag/котэ" style="left: 534px; top: 27px; width: 76px; height: 28px">котэ</a></li>
+ <li><a href="/tag/ВНЕЗАПНО" style="left: 501px; top: 293px; width: 146px; height: 23px">ВНЕЗАПНО</a></li>
+ <li><a href="/tag/юмор" style="left: 73px; top: 53px; width: 84px; height: 28px">юмор</a></li>
+ <li><a href="/tag/мысли" style="left: 202px; top: 179px; width: 102px; height: 21px">мысли</a></li>
+ <li><a href="/tag/pic" style="left: 400px; top: 78px; width: 33px; height: 38px">pic</a></li>
+ <li><a href="/tag/политота" style="left: 531px; top: 60px; width: 130px; height: 24px">политота</a></li>
+ <li><a href="/tag/WOT" style="left: 159px; top: 63px; width: 48px; height: 20px">WOT</a></li>
+ <li><a href="/tag/fail" style="left: 8px; top: 170px; width: 34px; height: 27px">fail</a></li>
+ <li><a href="/tag/погода" style="left: 670px; top: 126px; width: 24px; height: 93px">погода</a></li>
+ <li><a href="/tag/apple" style="left: 42px; top: 167px; width: 64px; height: 29px">apple</a></li>
+ <li><a href="/tag/jabber" style="left: 436px; top: 43px; width: 25px; height: 75px">jabber</a></li>
+ <li><a href="/tag/тян" style="left: 532px; top: 94px; width: 47px; height: 21px">тян</a></li>
+ <li><a href="/tag/work" style="left: 359px; top: 55px; width: 58px; height: 23px">work</a></li>
+ <li><a href="/tag/Python" style="left: 240px; top: 63px; width: 74px; height: 23px">Python</a></li>
+ <li><a href="/tag/Видео" style="left: 266px; top: 232px; width: 76px; height: 20px">Видео</a></li>
+ <li><a href="/tag/авто" style="left: 359px; top: 30px; width: 58px; height: 24px">авто</a></li>
+ <li><a href="/tag/Anime" style="left: 360px; top: 328px; width: 66px; height: 21px">Anime</a></li>
+ <li><a href="/tag/игры" style="left: 378px; top: 242px; width: 22px; height: 58px">игры</a></li>
+ <li><a href="/tag/вело" style="left: 176px; top: 9px; width: 18px; height: 54px">вело</a></li>
+ <li><a href="/tag/web" style="left: 661px; top: 219px; width: 22px; height: 47px">web</a></li>
+ <li><a href="/tag/YouTube" style="left: 498px; top: 316px; width: 81px; height: 24px">YouTube</a></li>
+ <li><a href="/tag/Вопрос" style="left: 208px; top: 18px; width: 22px; height: 72px">Вопрос</a></li>
+ <li><a href="/tag/железо" style="left: 159px; top: 318px; width: 75px; height: 16px">железо</a></li>
+ <li><a href="/tag/Microsoft" style="left: 20px; top: 146px; width: 86px; height: 21px">Microsoft</a></li>
+ <li><a href="/tag/video" style="left: 616px; top: 101px; width: 51px; height: 19px">video</a></li>
+ <li><a href="/tag/Россия" style="left: 32px; top: 242px; width: 68px; height: 16px">Россия</a></li>
+ <li><a href="/tag/java" style="left: 409px; top: 226px; width: 39px; height: 22px">java</a></li>
+ <li><a href="/tag/новости" style="left: 39px; top: 67px; width: 21px; height: 79px">новости</a></li>
+ <li><a href="/tag/интернет" style="left: 100px; top: 233px; width: 17px; height: 85px">интернет</a></li>
+ <li><a href="/tag/steam" style="left: 14px; top: 228px; width: 52px; height: 13px">steam</a></li>
+ <li><a href="/tag/слова" style="left: 501px; top: 272px; width: 51px; height: 18px">слова</a></li>
+ <li><a href="/tag/почта" style="left: 477px; top: 27px; width: 17px; height: 56px">почта</a></li>
+ <li><a href="/tag/help" style="left: 123px; top: 281px; width: 21px; height: 35px">help</a></li>
+ <li><a href="/tag/skype" style="left: 110px; top: 320px; width: 49px; height: 20px">skype</a></li>
+ <li><a href="/tag/debian" style="left: 461px; top: 47px; width: 16px; height: 51px">debian</a></li>
+ <li><a href="/tag/win" style="left: 505px; top: 104px; width: 27px; height: 16px">win</a></li>
+ <li><a href="/tag/Религия" style="left: 33px; top: 281px; width: 67px; height: 17px">Религия</a></li>
+ <li><a href="/tag/soft" style="left: 286px; top: 86px; width: 28px; height: 14px">soft</a></li>
+ <li><a href="/tag/Политика" style="left: 144px; top: 281px; width: 75px; height: 12px">Политика</a></li>
+ <li><a href="/tag/сны" style="left: 426px; top: 328px; width: 33px; height: 13px">сны</a></li>
+ <li><a href="/tag/Питер" style="left: 146px; top: 233px; width: 50px; height: 16px">Питер</a></li>
+ <li><a href="/tag/bash" style="left: 451px; top: 311px; width: 38px; height: 16px">bash</a></li>
+ <li><a href="/tag/code" style="left: 279px; top: 310px; width: 39px; height: 16px">code</a></li>
+ <li><a href="/tag/yandex" style="left: 19px; top: 263px; width: 56px; height: 18px">yandex</a></li>
+ <li><a href="/tag/firefox" style="left: 452px; top: 295px; width: 48px; height: 16px">firefox</a></li>
+ <li><a href="/tag/hardware" style="left: 230px; top: 40px; width: 67px; height: 18px">hardware</a></li>
+ <li><a href="/tag/git" style="left: 78px; top: 258px; width: 20px; height: 19px">git</a></li>
+ <li><a href="/tag/dev" style="left: 165px; top: 88px; width: 31px; height: 19px">dev</a></li>
+ <li><a href="/tag/mobile" style="left: 421px; top: 24px; width: 15px; height: 47px">mobile</a></li>
+ <li><a href="/tag/люди" style="left: 151px; top: 184px; width: 43px; height: 15px">люди</a></li>
+ <li><a href="/tag/php" style="left: 149px; top: 24px; width: 27px; height: 18px">php</a></li>
+ <li><a href="/tag/haskell" style="left: 271px; top: 293px; width: 48px; height: 16px">haskell</a></li>
+ <li><a href="/tag/стихи" style="left: 135px; top: 42px; width: 41px; height: 11px">стихи</a></li>
+ <li><a href="/tag/photo" style="left: 639px; top: 219px; width: 20px; height: 39px">photo</a></li>
+ <li><a href="/tag/чай" style="left: 448px; top: 220px; width: 27px; height: 14px">чай</a></li>
+ <li><a href="/tag/Опрос" style="left: 297px; top: 22px; width: 14px; height: 41px">Опрос</a></li>
+ <li><a href="/tag/Chrome" style="left: 311px; top: 25px; width: 48px; height: 17px">Chrome</a></li>
+ <li><a href="/tag/life" style="left: 255px; top: 311px; width: 23px; height: 16px">life</a></li>
+ <li><a href="/tag/opera" style="left: 226px; top: 232px; width: 38px; height: 14px">opera</a></li>
+ <li><a href="/tag/programming" style="left: 234px; top: 327px; width: 81px; height: 14px">programming</a></li>
+ <li><a href="/tag/дети" style="left: 15px; top: 197px; width: 31px; height: 13px">дети</a></li>
+ <li><a href="/tag/сериалы" style="left: 575px; top: 219px; width: 61px; height: 13px">сериалы</a></li>
+ <li><a href="/tag/учеба" style="left: 616px; top: 84px; width: 43px; height: 17px">учеба</a></li>
+</ul>
+
+<div id="bottom1">juick.com &copy; 2008-2016 &nbsp; <a href="/help/ru/contacts" rel="nofollow">Контакты</a> &#183; <a href="/help/" rel="nofollow">Помощь</a></div>
+
+<div id="signup">
+ Зарегистрироваться:
+ <div id="facebook"><a href="/_fblogin" rel="nofollow">Facebook</a></div>
+ <div id="vk"><a href="/_vklogin" rel="nofollow">ВКонтакте</a></div>
+ <div id="xmpp"><a href="#" onclick="$('#xmppinfo').toggle(); return false">XMPP</a>
+ <div id="xmppinfo">Отправьте <b>LOGIN</b> на <a href="xmpp:juick@@juick.com?message;body=LOGIN">juick@@juick.com</a></div>
+ </div>
+</div>
+<div id="signin"><a href="#" onclick="$('#signinform').toggle(); $('#nickinput').focus(); return false">Уже зарегистрированы?</a>
+ <div id="signinform"><form action="/login" method="POST">
+ <input class="txt" type="text" name="username" placeholder="Имя пользователя" id="nickinput"/>
+ <input class="txt" type="password" name="password" placeholder="Пароль"/>
+ <input class="submit" type="submit" value="OK"/>
+ </form></div>
+</div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/footer.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/footer.html
index 6978a2c0..6fbaecf2 100644
--- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/footer.html
+++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/footer.html
@@ -11,9 +11,7 @@
<a href="https://www.facebook.com/JuickCom" rel="nofollow" class="ico32-fb">Facebook</a>
</div>
<div id="footer-left">juick.com &copy; 2008-2016
- {% if links %}
- <br/>Спонсоры: {{ links }}
- {% endif %}
+ <br th:if="${links}"/>Спонсоры: ${links}
</div>
</div>
<script>
@@ -24,11 +22,11 @@
ga('create','UA-385578-4','juick.com');
ga('require','displayfeatures');
ga('send','pageview');
- {% if (sapeon) %}
+<th:block th:if="${sapeon}">
var _acic={dataProvider:10};
(function(){
var e=document.createElement('script');e.type='text/javascript';e.async=true;e.src='//www2.aci'+'nt.net/aci.js';
var t=document.getElementsByTagName('script')[0];t.parentNode.insertBefore(e,t);
})();
- {% endif %}
+</th:block>
</script> \ No newline at end of file
diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/homecolumn.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/homecolumn.html
index 5293918d..534e0368 100644
--- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/homecolumn.html
+++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/homecolumn.html
@@ -1,6 +1,4 @@
<p class="tags">
- {% include "views/partial/tags.html" %}
- {% if showAdv %}
- <a href="http://ru.wix.com/">конструктор сайтов</a>
- {% endif %}
+ <div th:replace="views/partial/tags">Tags</div>
+ <a href="http://ru.wix.com/" th:if="${showAdv}">конструктор сайтов</a>
</p> \ No newline at end of file
diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/navigation.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/navigation.html
index 2863d0c3..bd6359d7 100644
--- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/navigation.html
+++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/partial/navigation.html
@@ -9,29 +9,30 @@
</nav>
<div id="search">
<form action="/">
- <input type="text" name="search" class="text" placeholder="Поиск" value="{{ search }}"/>
+ <input type="text" name="search" class="text" placeholder="Поиск" th:value="${search}"/>
</form>
</div>
- <section id="headdiv">
- {% if visitor.getUID() > 0 %}
- <nav id="user">
- <ul>
- <li><a href="/?show=my">Моя лента</a></li>
- <li><a href="/pm/inbox">Приватные</a></li>
- <li><a href="/?show=discuss">Обсуждения</a></li>
- <li><a href="/?show=recommended">Рекомендации</a></li>
- </ul>
- </nav>
- <nav id="actions">
- <ul>
- <li><a href="/#post">Написать</a></li>
- <li><a href="/{{ visitor.getName() }}">@{{ visitor.getName() }}</a></li>
- <li><a href="/logout">Выйти</a></li>
- </ul>
- </nav>
- {% else %}
- <p>Чтобы добавлять сообщения и комментарии, <a href="#" onclick="return Juick.openDialogLogin()">представьтесь</a>.
- </p>
- {% endif %}
+ <section id="headdiv" th:switch="${visitor.getUid() > 0}">
+ <th:block th:case="true">
+ <nav id="user">
+ <ul>
+ <li><a href="/?show=my">Моя лента</a></li>
+ <li><a href="/pm/inbox">Приватные</a></li>
+ <li><a href="/?show=discuss">Обсуждения</a></li>
+ <li><a href="/?show=recommended">Рекомендации</a></li>
+ </ul>
+ </nav>
+ <nav id="actions">
+ <ul>
+ <li><a href="/#post">Написать</a></li>
+ <li><a href="/${visitor.getName()}" th:text="@${visitor.getName()}">@ugnich</a></li>
+ <li><a href="/logout">Выйти</a></li>
+ </ul>
+ </nav>
+ </th:block>
+ <th:block th:case="false">
+ <p>Чтобы добавлять сообщения и комментарии, <a href="/login">представьтесь</a>.
+ </p>
+ </th:block>
</section>
</header>
diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_inbox.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_inbox.html
new file mode 100644
index 00000000..7ab557f5
--- /dev/null
+++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_inbox.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org"
+ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+ layout:decorate="~{layout/mainLayout}">
+<head>
+ <title th:text="${title}">Inbox title</title>
+</head>
+
+<body>
+<section id="content">
+ <ul layout:fragment="content" id="private-messages" th:if="${not #lists.isEmpty(msgs)}">
+ <li class="msg" th:each="msg:${msgs}">
+ <div class="msg-cont">
+ <div class="msg-header">
+ @<a href="/${msg.getUser().getName()}/" th:text="${msg.getUser().getName()}">ugnich</a>:
+ <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>
+ <div class="msg-ts" th:text="${msg.getDate()}">01.01.1970</div>
+ </div>
+
+ <div class="msg-txt" th:utext="${msg.getText()}">Lorem ipsum</div>
+
+ <form action="/pm/send" method="POST" enctype="multipart/form-data">
+ <input type="hidden" name="uname" th:value="${msg.getUser().getName()}"/>
+ <div class="msg-comment">
+ <div class="ta-wrapper">
+ <textarea name="body" rows="1" class="replypm" placeholder="Написать ответ"></textarea>
+ </div>
+ </div>
+ </form>
+
+ </div>
+ </li>
+ </ul>
+</section>
+<aside id="column">
+ <p th:replace="views/partial/homecolumn.html">Main side column</p>
+</aside>
+
+</body>
+</html> \ No newline at end of file
diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_sent.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_sent.html
new file mode 100644
index 00000000..f2c05ad3
--- /dev/null
+++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_sent.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org"
+ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+ layout:decorate="~{layout/mainLayout}">
+<head>
+ <title th:text="${title}">Settings title</title>
+</head>
+
+<body>
+<section id="content">
+ <div layout:fragment="content">
+ <form action="/pm/send" method="POST" enctype="multipart/form-data">
+ <div class="newpm">
+ <div class="newpm-to">To: <input type="text" name="uname" placeholder="username" th:value="${uname}"/></div>
+ <div class="newpm-body"><textarea name="body" rows="2"></textarea></div>
+ <div class="newpm-send"><input type="submit" value="OK"/></div>
+ </div>
+ </form>
+ <ul id="private-messages" th:if="#{not lists.isEmpty(msgs)}">
+ <li class="msg" th:each="msg:${msgs}">
+ <div class="msg-cont">
+ <div class="msg-header">
+ @<a href="/${msg.getUser().getName()}/" th:text="${msg.getUser().getName()}">ugnich</a>:
+ <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>
+ <div class="msg-ts" th:text="${msg.getDate()}">01.01.1970</div>
+ </div>
+ <div class="msg-txt" th:utext="${msg.getText()}"></div>
+ </div>
+ </li>
+ </ul>
+ </div>
+</section>
+<aside id="column">
+ <p th:replace="views/partial/homecolumn.html">Main side column</p>
+</aside>
+
+</body>
+</html>
diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_about.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_about.html
index ff82b542..b93a699e 100644
--- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_about.html
+++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_about.html
@@ -10,12 +10,12 @@
<section id="content">
<article layout:fragment="content">
<form action="/settings" method="POST" enctype="multipart/form-data">
- <p>Full name: <input type="text" name="fullname" value="{{ userinfo.getFullName() }}"/></p>
- <p>Country: <input type="text" name="country" value="{{ userinfo.getCountry() }}"/></p>
- <p>URL: <input type="text" name="url" value="{{ userinfo.getUrl() }}" size="32"/><br/>
+ <p>Full name: <input type="text" name="fullname" value="${userinfo.getFullName()}"/></p>
+ <p>Country: <input type="text" name="country" value="${userinfo.getCountry()}"/></p>
+ <p>URL: <input type="text" name="url" value="${userinfo.getUrl()}" size="32"/><br/>
<small>Please, start with &quot;http://&quot;</small></p>
<p>About:<br/>
- <input type="text" name="descr" value="{{ userinfo.getDescription() }}" style="width: 100%"/><br/>
+ <input type="text" name="descr" value="${userinfo.getDescription()}" style="width: 100%"/><br/>
<small>Max. 255 symbols</small></p>
<p>Avatar: <input type="file" name="avatar"/><br/>
<small>Recommendations: PNG, 96x96, &lt;50Kb. Also, JPG and GIF supported.</small></p>