aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--juick-server-core/src/main/java/com/juick/service/MessagesService.java2
-rw-r--r--juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java51
-rw-r--r--juick-server-jdbc/src/test/java/com/juick/service/MessageServiceTest.java14
-rw-r--r--juick-server/src/main/java/com/juick/server/api/Messages.java11
-rw-r--r--juick-www/src/main/java/com/juick/www/controllers/Messages.java21
-rw-r--r--juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/FormatMessageFilter.java6
-rw-r--r--juick-www/src/main/resources/templates/views/macros/tree.html57
-rw-r--r--juick-www/src/main/resources/templates/views/partial/thread_list.html49
-rw-r--r--juick-www/src/main/resources/templates/views/partial/thread_tree.html2
-rw-r--r--juick-www/src/main/resources/templates/views/thread.html64
-rw-r--r--juick-www/src/main/static/scripts.js60
-rw-r--r--juick-www/src/test/java/com/juick/www/WebAppTests.java4
13 files changed, 99 insertions, 244 deletions
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 568c50bf..8941bfbb 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-all.zip
diff --git a/juick-server-core/src/main/java/com/juick/service/MessagesService.java b/juick-server-core/src/main/java/com/juick/service/MessagesService.java
index b90cca79..2a3e701e 100644
--- a/juick-server-core/src/main/java/com/juick/service/MessagesService.java
+++ b/juick-server-core/src/main/java/com/juick/service/MessagesService.java
@@ -104,7 +104,5 @@ public interface MessagesService {
List<ResponseReply> getLastReplies(int hours);
- List<com.juick.Message> getNotifications(User user, LocalDateTime before);
-
List<Integer> getPopularCandidates();
}
diff --git a/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java
index d7067901..fd93a5e1 100644
--- a/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java
+++ b/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java
@@ -98,6 +98,13 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
msg.setText(rs.getString(20));
msg.setReplyQuote(MessageUtils.formatQuote(rs.getString(21)));
msg.setUpdated(rs.getTimestamp(22).toInstant());
+ int quoteUid = rs.getInt(23);
+ if (quoteUid > 0) {
+ User quoteUser = new User();
+ quoteUser.setUid(quoteUid);
+ quoteUser.setName(rs.getString(24));
+ msg.setTo(quoteUser);
+ }
try {
imagesService.setAttachmentMetadata(imgDir, baseImagesUrl, msg);
} catch (Exception e) {
@@ -306,7 +313,8 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
+ "messages.readonly, messages.privacy, messages.replies,"
+ "messages.attach, messages.place_id, messages.lat,"
+ "messages.lon, COUNT(favorites.user_id) as likes, messages.hidden,"
- + "txt.tags, txt.repliesby, txt.txt, '' as q, messages.updated FROM messages "
+ + "txt.tags, txt.repliesby, txt.txt, '' as q, messages.updated, 0 as to_uid, "
+ + "NULL as to_name FROM messages "
+ "INNER JOIN users ON messages.user_id = users.id "
+ "INNER JOIN messages_txt AS txt "
+ "ON messages.message_id = txt.message_id "
@@ -327,10 +335,14 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
List<com.juick.Message> list = getJdbcTemplate().query(
"SELECT replies.user_id, users.nick,"
+ "replies.replyto, replies.ts,"
- + "replies.attach, replies.txt, IFNULL(q.txt,t.txt) as quote "
+ + "replies.attach, replies.txt, IFNULL(q.txt,t.txt) as quote, "
+ + "COALESCE(q.user_id, m.user_id) AS to_uid, COALESCE(qu.nick, mu.nick) AS to_name "
+ "FROM replies INNER JOIN users ON replies.user_id = users.id "
+ "LEFT JOIN replies q ON replies.message_id = q.message_id and replies.replyto = q.reply_id "
+ "LEFT JOIN messages_txt t ON replies.message_id = t.message_id "
+ + "LEFT JOIN messages m ON replies.message_id = m.message_id "
+ + "LEFT JOIN users qu ON q.user_id=qu.id "
+ + "LEFT JOIN users mu ON m.user_id=mu.id "
+ "WHERE replies.message_id = ? AND replies.reply_id = ?",
(rs, num) -> {
Message msg = new Message();
@@ -349,6 +361,13 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
if (!StringUtils.isEmpty(quote)) {
msg.setReplyQuote(MessageUtils.formatQuote(quote));
}
+ int quoteUid = rs.getInt(8);
+ if (quoteUid > 0) {
+ User quoteUser = new User();
+ quoteUser.setUid(quoteUid);
+ quoteUser.setName(rs.getString(9));
+ msg.setTo(quoteUser);
+ }
return msg;
},
@@ -736,7 +755,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
+ "messages.attach,messages.place_id,messages.lat,"
+ "messages.lon,COUNT(favorites.user_id) AS likes,messages.hidden,"
+ "messages_txt.tags,messages_txt.repliesby, messages_txt.txt, '' as q, "
- + "messages.updated "
+ + "messages.updated, 0 as to_uid, NULL as to_name "
+ "FROM (messages INNER JOIN messages_txt "
+ "ON messages.message_id=messages_txt.message_id) "
+ "INNER JOIN users ON messages.user_id=users.id "
@@ -763,11 +782,15 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
"0 as lon, 0 as likes, 0 as hidden, " +
"NULL as tags, NULL as repliesby, replies.txt, " +
"IFNULL(qw.txt, t.txt) as q, " +
- "NOW() " +
+ "NOW(), " +
+ "COALESCE(qw.user_id, m.user_id) as to_uid, COALESCE(qu.nick, mu.nick) as to_name " +
"FROM replies INNER JOIN users " +
"ON replies.user_id = users.id " +
"LEFT JOIN replies qw ON replies.message_id = qw.message_id and replies.replyto = qw.reply_id " +
"LEFT JOIN messages_txt t on replies.message_id = t.message_id " +
+ "LEFT JOIN messages m on replies.message_id = m.message_id " +
+ "LEFT JOIN users qu ON qw.user_id=qu.id " +
+ "LEFT JOIN users mu ON m.user_id=mu.id " +
"WHERE replies.message_id = :mid ORDER BY replies.reply_id ASC",
new MapSqlParameterSource("mid", mid),
new MessageMapper());
@@ -883,26 +906,6 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
return reply;
}, -hours);
}
-
- @Transactional(readOnly = true)
- @Override
- public List<com.juick.Message> getNotifications(User user, LocalDateTime before) {
- return getNamedParameterJdbcTemplate().query("SELECT n.message_id as mid, n.reply_id, " +
- "n.replyto, " +
- "n.user_id, users.nick, users.banned, 0 as ago, n.ts, 0 as readonly, 0 as privacy, " +
- "0 as replies, n.attach, 0 as place_id, 0 as lat, 0 as lon, 0 as likes, 0 as hidden, " +
- "NULL as tags, NULL as repliesby, n.txt, IFNULL(qw.txt, t.txt) as q, NOW() " +
- "FROM (SELECT * FROM replies WHERE EXISTS (SELECT 1 FROM subscr_messages WHERE suser_id=:uid " +
- "AND replies.user_id!=:uid AND replies.message_id=message_id " +
- (before != null ? "AND replies.ts < :before " : StringUtils.EMPTY) +
- ")) as n LEFT JOIN users " +
- "ON n.user_id = users.id LEFT JOIN replies qw ON n.message_id = qw.message_id " +
- "AND n.replyto = qw.reply_id LEFT JOIN messages_txt t on n.message_id = t.message_id " +
- "ORDER BY ts DESC LIMIT 20", new MapSqlParameterSource()
- .addValue("uid", user.getUid())
- .addValue("before", before),
- new MessageMapper());
- }
@Transactional(readOnly = true)
@Override
public List<Integer> getPopularCandidates() {
diff --git a/juick-server-jdbc/src/test/java/com/juick/service/MessageServiceTest.java b/juick-server-jdbc/src/test/java/com/juick/service/MessageServiceTest.java
index 4ebfe056..d24a6281 100644
--- a/juick-server-jdbc/src/test/java/com/juick/service/MessageServiceTest.java
+++ b/juick-server-jdbc/src/test/java/com/juick/service/MessageServiceTest.java
@@ -159,8 +159,20 @@ public class MessageServiceTest extends AbstractJUnit4SpringContextTests {
User ugnich = userService.getUserByUID(ugnich_id).orElse(new User());
int rid = messagesService.createReply(msg2.getMid(), 0, ugnich.getUid(), "bla-bla", null);
assertEquals(1, rid);
+ assertThat(msg2.getTo(), equalTo(null));
+ Message reply = messagesService.getReply(msg2.getMid(), rid);
+ assertThat(reply.getTo().getName(), equalTo(user.getName()));
+ List<Message> replies = messagesService.getReplies(msg2.getMid());
+ assertThat(replies.size(), equalTo(1));
+ assertThat(replies.get(0), equalTo(reply));
+ int ridToReply = messagesService.createReply(msg2.getMid(), 1, ugnich_id, "blax2", null);
+ Message reply2 = messagesService.getReply(msg2.getMid(), ridToReply);
+ assertThat(reply.getTo().getName(), equalTo(user.getName()));
+ List<Message> replies2 = messagesService.getReplies(msg2.getMid());
+ assertThat(replies2.size(), equalTo(2));
+ assertThat(replies2.get(1), equalTo(reply2));
Message msg3 = messagesService.getMessage(mid2);
- assertEquals(1, msg3.getReplies());
+ assertEquals(2, msg3.getReplies());
assertEquals("weather", msg3.getTags().get(0).getName());
assertEquals(ugnich.getUid(), userService.checkPassword(ugnich.getName(), "x"));
assertEquals(-1, userService.checkPassword(ugnich.getName(), "xy"));
diff --git a/juick-server/src/main/java/com/juick/server/api/Messages.java b/juick-server/src/main/java/com/juick/server/api/Messages.java
index 87229131..769d1474 100644
--- a/juick-server/src/main/java/com/juick/server/api/Messages.java
+++ b/juick-server/src/main/java/com/juick/server/api/Messages.java
@@ -133,17 +133,6 @@ public class Messages {
}
return ResponseEntity.ok(messagesService.getMessages(mids));
}
-
- @GetMapping("/messages/notifications")
- public ResponseEntity<List<com.juick.Message>> getNotifications(
- @RequestParam(required = false) Long before
- ) {
- User visitor = UserUtils.getCurrentUser();
- LocalDateTime beforeTime = before != null ?
- LocalDateTime.ofInstant(Instant.ofEpochMilli(before), ZoneId.systemDefault())
- : null;
- return ResponseEntity.ok(messagesService.getNotifications(visitor, beforeTime));
- }
@GetMapping("/messages/discussions")
public List<Message> getDiscussions(
@RequestParam(required = false, defaultValue = "0") Long to) {
diff --git a/juick-www/src/main/java/com/juick/www/controllers/Messages.java b/juick-www/src/main/java/com/juick/www/controllers/Messages.java
index c83bb356..11dafda3 100644
--- a/juick-www/src/main/java/com/juick/www/controllers/Messages.java
+++ b/juick-www/src/main/java/com/juick/www/controllers/Messages.java
@@ -506,8 +506,8 @@ public class Messages {
protected String threadAction(ModelMap model,
@PathVariable String uname,
@PathVariable int mid,
- @CookieValue(name = "sape_cookie", required = false, defaultValue = StringUtils.EMPTY) String sapeCookie,
- @RequestParam(required = false, value = "view") String paramView) {
+ @CookieValue(name = "sape_cookie",
+ required = false, defaultValue = StringUtils.EMPTY) String sapeCookie) {
com.juick.User visitor = UserUtils.getCurrentUser();
if (!messagesService.canViewThread(mid, visitor.getUid())) {
@@ -533,29 +533,12 @@ public class Messages {
}
model.addAttribute("msg", msg);
- boolean listview = false;
- 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;
- }
- model.addAttribute("listview", listview);
String title = msg.getUser().getName() + ": " + msg.getTagsString();
model.addAttribute("title", title);
model.addAttribute("visitor", visitor);
String headers = "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"@" + msg.getUser().getName() + "\" href=\"//rss.juick.com/" + msg.getUser().getName() + "/blog\"/>";
String pageUrl = "https://juick.com/" + msg.getUser().getName() + "/" + msg.getMid();
- if (paramView != null) {
- headers += "<link rel=\"canonical\" href=\"" + pageUrl + "\"/>";
- }
if (msg.Hidden) {
headers += "<meta name=\"robots\" content=\"noindex\"/>";
}
diff --git a/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/FormatMessageFilter.java b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/FormatMessageFilter.java
index b492f121..14af2539 100644
--- a/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/FormatMessageFilter.java
+++ b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/FormatMessageFilter.java
@@ -35,8 +35,10 @@ public class FormatMessageFilter implements Filter {
if (input instanceof Message) {
Message msg = (Message) input;
boolean isCode = msg.getTags().stream().anyMatch(t -> t.getName().equals("code"));
- String formattedMessage = isCode ? MessageUtils.formatMessageCode(StringUtils.defaultString(msg.getText()))
- : MessageUtils.formatMessage(StringUtils.defaultString(msg.getText()));
+ String msgTxt = msg.getRid() > 0 ? String.format("@%s, %s", msg.getTo().getName(), StringUtils.defaultString(msg.getText()))
+ : StringUtils.defaultString(msg.getText());
+ String formattedMessage = isCode ? MessageUtils.formatMessageCode(msgTxt)
+ : MessageUtils.formatMessage(msgTxt);
return new SafeString(formattedMessage);
}
throw new IllegalArgumentException("invalid input");
diff --git a/juick-www/src/main/resources/templates/views/macros/tree.html b/juick-www/src/main/resources/templates/views/macros/tree.html
deleted file mode 100644
index 71ffd74b..00000000
--- a/juick-www/src/main/resources/templates/views/macros/tree.html
+++ /dev/null
@@ -1,57 +0,0 @@
-{% macro tree(replies, visitor, level, margin, hidden) %}
-{% for msg in replies %}
- {% if msg.replyto == level %}
- <li id="{{ msg.rid }}" style="margin-left: {{ margin }}px;{% if hidden %}display: none;{% endif %}" class="msg">
- <div class="msg-cont">
- <div class="msg-header">
-{% if not msg.user.banned %}
- <a href="/{{ msg.user.name }}/">{{ msg.user.name }}</a>
- <div class="msg-avatar"><a href="/{{ msg.user.name }}/">
- <img src="//i.juick.com/a/{{ msg.user.uid }}.png" alt="{{ msg.user.name }}"/></a>
- </div>
-{% else %}
- [удалено]:
- <div class="msg-avatar">
- <img src="//i.juick.com/av-96.png"/>
- </div>
-{% endif %}
- <div class="msg-ts">
- <a href="/{{ msg.mid }}#{{ msg.rid }}">
- <time datetime="{{ msg.timestamp | timestamp | date('yyyy-MM-dd HH:mm:ss') }}Z"
- title="{{ msg.timestamp | timestamp | date('yyyy-MM-dd HH:mm:ss') }} GMT">
- {{ msg.timestamp | prettyTime }}
- </time>
- </a>
- </div>
- </div>
- <div class="msg-txt">{{ msg | formatMessage }}</div>
- {% if msg.AttachmentType is not empty %}
- <div class="msg-media">
- <a href="//i.juick.com/p/{{ msg.mid }}-{{ msg.rid }}.{{ msg.AttachmentType }}" data-fname="{{ msg.mid }}-{{ msg.rid }}.{{ msg.AttachmentType }}">
- <img src="//i.juick.com/photos-512/{{ msg.mid }}-{{ msg.rid }}.{{ msg.AttachmentType }}" alt=""/>
- </a>
- </div>
- {% endif %}
- <div class="msg-links">/{{ msg.rid }}
-{% if msg.replyto > 0 %}
- {{ i18n("messages","reply.inReplyTo") }} <a href="#{{ msg.replyto }}">/{{ msg.replyto }}</a>
-{% endif %}
-{% if msg.VisitorCanComment %}
- &middot; <a href="/post?body=%23{{ msg.mid }}/{{ msg.rid }}%20" class="a-thread-comment">{{ i18n("messages","reply.reply") }}</a></div>
- <div class="msg-comment-target msg-comment-hidden"></div>
-{% elseif visitor.uid == 0 %}
- &middot; <a href="#" class="a-login">{{ i18n("messages","reply.reply") }}</a></div>
-{% endif %}
-
-{% if level == 0 and msg.childsCount > 1 and replies.size() > 10 %}
- <div class="msg-comments"><a href="#">{{ msg | formatReplies }}</a></div>
-{% endif %}
- </li>
- {% 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/resources/templates/views/partial/thread_list.html b/juick-www/src/main/resources/templates/views/partial/thread_list.html
deleted file mode 100644
index f273dec7..00000000
--- a/juick-www/src/main/resources/templates/views/partial/thread_list.html
+++ /dev/null
@@ -1,49 +0,0 @@
-{% for msg in replies %}
-<li id="{{ msg.rid }}" class="msg">
- <div class="msg-cont">
- <div class="msg-header">
- {% if not msg.user.banned %}
- <a href="/{{ msg.user.name }}/">{{ msg.user.name }}</a>
- <div class="msg-avatar"><a href="/{{ msg.user.name }}/">
- <img src="//i.juick.com/a/{{ msg.user.uid }}.png" alt="{{ msg.user.name }}"/></a>
- </div>
- {% else %}
- [удалено]:
- <div class="msg-avatar">
- <img src="//i.juick.com/av-96.png"/>
- </div>
- {% endif %}
- <div class="msg-ts">
- <a href="/{{ msg.mid }}#{{ msg.rid }}">
- <time datetime="{{ msg.timestamp | timestamp | date('yyyy-MM-dd HH:mm:ss') }}Z"
- title="{{ msg.timestamp | timestamp | date('yyyy-MM-dd HH:mm:ss') }} GMT">
- {{ msg.timestamp | prettyTime }}
- </time>
- </a>
- </div>
- </div>
- <div class="msg-txt">{{ msg | formatMessage }}</div>
- {% if msg.AttachmentType is not empty %}
- <div class="msg-media">
- <a href="//i.juick.com/p/{{ msg.mid }}-{{ msg.rid }}.{{ msg.AttachmentType }}" data-fname="{{ msg.mid }}-{{ msg.rid }}.{{ msg.AttachmentType }}">
- <img src="//i.juick.com/photos-512/{{ msg.mid }}-{{ msg.rid }}.{{ msg.AttachmentType }}" alt=""/>
- </a>
- </div>
- {% endif %}
- <div class="msg-links">/{{ msg.rid }}
- {% if msg.replyto > 0 %}
- {{ i18n("messages","reply.inReplyTo") }} <a href="#{{ msg.replyto }}">/{{ msg.replyto }}</a>
- {% endif %}
- {% if msg.VisitorCanComment %}
- &middot; <a href="/post?body=%23{{ msg.mid }}/{{ msg.rid }}%20" class="a-thread-comment">{{ i18n("messages","reply.reply") }}</a>
- </div>
- <div class="msg-comment-target msg-comment-hidden"></div>
- {% elseif visitor.uid == 0 %}
- &middot; <a href="#" class="a-login">{{ i18n("messages","reply.reply") }}</a>
- </div>
- {% else %}
- </div>
- {% endif %}
- </div>
-</li>
-{% endfor %} \ No newline at end of file
diff --git a/juick-www/src/main/resources/templates/views/partial/thread_tree.html b/juick-www/src/main/resources/templates/views/partial/thread_tree.html
deleted file mode 100644
index f207b8e0..00000000
--- a/juick-www/src/main/resources/templates/views/partial/thread_tree.html
+++ /dev/null
@@ -1,2 +0,0 @@
-{% import "views/macros/tree" %}
-{{ tree(replies, visitor, 0, 0, false) }} \ No newline at end of file
diff --git a/juick-www/src/main/resources/templates/views/thread.html b/juick-www/src/main/resources/templates/views/thread.html
index 2115f442..ae429365 100644
--- a/juick-www/src/main/resources/templates/views/thread.html
+++ b/juick-www/src/main/resources/templates/views/thread.html
@@ -108,25 +108,59 @@
</li>
</ul>
<div class="title2">
- <div class="title2-right">
- {% if listview %}
- <a href="?view=tree" rel="nofollow">{{ i18n("messages","replies.showAsTree") }}</a>
- {% else %}
- {% if foldable %}
- <span id="unfoldall"><a href="#">{{ i18n("messages","replies.unfoldAll") }}</a> &middot; </span>
- {% endif %}
- <a href="?view=list" rel="nofollow">{{ i18n("messages","replies.showAsList") }}</a>
- {% endif %}
- </div>
<h2>{{ i18n("messages","reply.replies") }} ({{ replies.size() }})</h2>
</div>
<ul id="replies">
- {% if (listview) %}
- {% include "views/partial/thread_list" %}
- {% else %}
- {% include "views/partial/thread_tree" %}
- {% endif %}
+ {% for msg in replies %}
+ <li id="{{ msg.rid }}" class="msg">
+ <div class="msg-cont">
+ <div class="msg-header">
+ {% if not msg.user.banned %}
+ <a href="/{{ msg.user.name }}/">{{ msg.user.name }}</a>
+ <div class="msg-avatar"><a href="/{{ msg.user.name }}/">
+ <img src="//i.juick.com/a/{{ msg.user.uid }}.png" alt="{{ msg.user.name }}"/></a>
+ </div>
+ {% else %}
+ [удалено]:
+ <div class="msg-avatar">
+ <img src="//i.juick.com/av-96.png"/>
+ </div>
+ {% endif %}
+ <div class="msg-ts">
+ <a href="/{{ msg.mid }}#{{ msg.rid }}">
+ <time datetime="{{ msg.timestamp | timestamp | date('yyyy-MM-dd HH:mm:ss') }}Z"
+ title="{{ msg.timestamp | timestamp | date('yyyy-MM-dd HH:mm:ss') }} GMT">
+ {{ msg.timestamp | prettyTime }}
+ </time>
+ </a>
+ </div>
+ </div>
+ <div class="msg-txt">{{ msg | formatMessage }}</div>
+ {% if msg.AttachmentType is not empty %}
+ <div class="msg-media">
+ <a href="//i.juick.com/p/{{ msg.mid }}-{{ msg.rid }}.{{ msg.AttachmentType }}" data-fname="{{ msg.mid }}-{{ msg.rid }}.{{ msg.AttachmentType }}">
+ <img src="//i.juick.com/photos-512/{{ msg.mid }}-{{ msg.rid }}.{{ msg.AttachmentType }}" alt=""/>
+ </a>
+ </div>
+ {% endif %}
+ <div class="msg-links">/{{ msg.rid }}
+ {% if msg.replyto > 0 %}
+ {{ i18n("messages","reply.inReplyTo") }} <a href="#{{ msg.replyto }}">/{{ msg.replyto }}</a>
+ {% endif %}
+ {% if msg.VisitorCanComment %}
+ &middot; <a href="/post?body=%23{{ msg.mid }}/{{ msg.rid }}%20" class="a-thread-comment">{{ i18n("messages","reply.reply") }}</a>
+ </div>
+ <div class="msg-comment-target msg-comment-hidden"></div>
+ {% elseif visitor.uid == 0 %}
+ &middot; <a href="#" class="a-login">{{ i18n("messages","reply.reply") }}</a>
+ </div>
+ {% else %}
+ </div>
+ {% endif %}
+ </div>
+ </li>
+ {% endfor %}
</ul>
{% endblock %}
{% block "column" %}
diff --git a/juick-www/src/main/static/scripts.js b/juick-www/src/main/static/scripts.js
index 588e4fdb..c6293266 100644
--- a/juick-www/src/main/static/scripts.js
+++ b/juick-www/src/main/static/scripts.js
@@ -187,11 +187,6 @@ function wsShutdown() {
}
}
-function isTreeMode() {
- // relies on UserThread.printReplies implementation TODO keep this in cookie or something
- return document.querySelector('.title2-right > a').href.match(/\?view=(\w+)/)[1] == 'list';
-}
-
function wsIncomingReply(msg) {
let content = document.getElementById('content');
if (!content) { return; }
@@ -234,15 +229,7 @@ function wsIncomingReply(msg) {
killy.embedLinksToX(li.querySelector('.msg-cont'), '.msg-links', '.msg-txt a');
- if (isTreeMode() && (msg.replyto > 0)) {
- let p = document.getElementById(msg.replyto);
- let m = parseInt(p.style.marginLeft) + 20;
- while (p.nextElementSibling && (parseInt(p.nextElementSibling.style.marginLeft) >= m)) { p = p.nextElementSibling; }
- li.style.marginLeft = m + 'px';
- p.parentNode.insertBefore(li, p.nextSibling);
- } else {
- document.getElementById('replies').appendChild(li);
- }
+ document.getElementById('replies').appendChild(li);
updateRepliesCounter();
}
@@ -309,29 +296,6 @@ function newMessage(evt) {
}
}
-function showMoreReplies(el, id) {
- var foldedReplies = el.closest('li').querySelector('.msg-comments');
- if (!foldedReplies) { return; }
- foldedReplies.style.display = 'none';
-
- var replies = document.querySelectorAll('#replies>li'),
- flagshow = 0,
- i = 0;
- for (; i < replies.length; i += 1) {
- if (flagshow == 1) {
- if (replies[i].style.display == 'none') {
- replies[i].style.display = 'block';
- } else {
- break;
- }
- }
- if (replies[i].id == id) {
- flagshow = 1;
- }
- }
- return false;
-}
-
function showCommentForm(mid, rid) {
let reply = document.getElementById(rid);
let formTarget = reply.querySelector('div.msg-cont .msg-comment-target');
@@ -422,19 +386,6 @@ function attachMessagePhoto(div) {
}
}
-function unfoldReply() {
- var anchor = window.location.hash.substring(1);
- if ((0 + anchor) > 0) {
- var el = document.getElementById(anchor);
- if (!el) { return; }
- while (el.style.display === 'none') {
- el = el.previousElementSibling;
- }
- showMoreReplies(el, el.getAttribute('id'));
- window.location.replace(window.location.hash);
- }
-}
-
function showMessageLinksDialog(mid, rid) {
let hlink = window.location.protocol + '//juick.com/' + mid;
let mlink = '#' + mid;
@@ -667,13 +618,6 @@ ready(function () {
var pageMID = content.getAttribute('data-mid');
if (pageMID > 0) {
document.querySelectorAll('li.msg').forEach(li => {
- let showMoreBtn = li.querySelector('.msg-comments');
- if (showMoreBtn) {
- showMoreBtn.addEventListener('click', function (e) {
- showMoreReplies(e.target, li.id);
- e.preventDefault();
- });
- }
let showReplyFormBtn = li.querySelector('.a-thread-comment');
if (showReplyFormBtn) {
showReplyFormBtn.addEventListener('click', function (e) {
@@ -784,9 +728,7 @@ ready(function () {
article.classList.add('nsfw');
}
});
- unfoldReply();
initWS();
- window.addEventListener('hashchange', unfoldReply);
window.addEventListener('pagehide', wsShutdown);
diff --git a/juick-www/src/test/java/com/juick/www/WebAppTests.java b/juick-www/src/test/java/com/juick/www/WebAppTests.java
index 57094c37..726a4612 100644
--- a/juick-www/src/test/java/com/juick/www/WebAppTests.java
+++ b/juick-www/src/test/java/com/juick/www/WebAppTests.java
@@ -191,7 +191,7 @@ public class WebAppTests {
assertThat(threadPage.getWebResponse().getStatusCode(), equalTo(404));
}
@Test
- public void repliesTree() throws IOException {
+ public void repliesList() throws IOException {
int mid = messagesService.createMessage(ugnich.getUid(), "hello", null, null);
IntStream.range(1, 15).forEach(i ->
messagesService.createReply(mid, i-1, freefd.getUid(), String.valueOf(i-1), null ));
@@ -203,7 +203,7 @@ public class WebAppTests {
StyleElement display = e.getStyleElement("display");
return display == null || !display.getValue().equals("none");
}).count();
- assertThat(visibleItems, equalTo(1L));
+ assertThat(visibleItems, equalTo(14L));
}
@Test
public void userShouldNotSeeReplyButtonToBannedUser() throws Exception {