Каналы: новый роутинг, поиск, вход-возврат, удаление просмотров и документация

This commit is contained in:
AidarKC
2026-05-08 01:15:54 +03:00
parent 6774c26ea1
commit acdd6c928b
18 changed files with 657 additions and 458 deletions
@@ -49,11 +49,9 @@ import server.logic.ws_protocol.JSON.handlers.channels.ChannelNamesStateBootstra
import server.logic.ws_protocol.JSON.handlers.channels.Net_GetChannelMessages_Handler;
import server.logic.ws_protocol.JSON.handlers.channels.Net_GetMessageThread_Handler;
import server.logic.ws_protocol.JSON.handlers.channels.Net_ListSubscriptionsFeed_Handler;
import server.logic.ws_protocol.JSON.handlers.channels.Net_MarkChannelMessagesSeen_Handler;
import server.logic.ws_protocol.JSON.handlers.channels.entyties.Net_GetChannelMessages_Request;
import server.logic.ws_protocol.JSON.handlers.channels.entyties.Net_GetMessageThread_Request;
import server.logic.ws_protocol.JSON.handlers.channels.entyties.Net_ListSubscriptionsFeed_Request;
import server.logic.ws_protocol.JSON.handlers.channels.entyties.Net_MarkChannelMessagesSeen_Request;
import server.logic.ws_protocol.JSON.handlers.connections.Net_GetUserConnectionsGraph_Handler;
import server.logic.ws_protocol.JSON.handlers.connections.Net_AddCloseFriend_Handler;
import server.logic.ws_protocol.JSON.handlers.connections.Net_ListContacts_Handler;
@@ -131,7 +129,6 @@ public final class JsonHandlerRegistry {
Map.entry("ListSubscriptionsFeed", new Net_ListSubscriptionsFeed_Handler()),
Map.entry("GetChannelMessages", new Net_GetChannelMessages_Handler()),
Map.entry("GetMessageThread", new Net_GetMessageThread_Handler()),
Map.entry("MarkChannelMessagesSeen", new Net_MarkChannelMessagesSeen_Handler()),
Map.entry("ListContacts", new Net_ListContacts_Handler()),
Map.entry("GetUserConnectionsGraph", new Net_GetUserConnectionsGraph_Handler()),
Map.entry("AddCloseFriend", new Net_AddCloseFriend_Handler()),
@@ -187,7 +184,6 @@ public final class JsonHandlerRegistry {
Map.entry("ListSubscriptionsFeed", Net_ListSubscriptionsFeed_Request.class),
Map.entry("GetChannelMessages", Net_GetChannelMessages_Request.class),
Map.entry("GetMessageThread", Net_GetMessageThread_Request.class),
Map.entry("MarkChannelMessagesSeen", Net_MarkChannelMessagesSeen_Request.class),
Map.entry("ListContacts", Net_ListContacts_Request.class),
Map.entry("GetUserConnectionsGraph", Net_GetUserConnectionsGraph_Request.class),
Map.entry("AddCloseFriend", Net_AddCloseFriend_Request.class),
@@ -212,111 +212,6 @@ final class ChannelsReadSupport {
}
}
static int countViews(Connection c, String bch, int blockNumber, byte[] blockHash) throws SQLException {
String sql = """
SELECT COUNT(*) AS cnt
FROM message_views_state
WHERE to_bch_name=? AND to_block_number=? AND to_block_hash=?
""";
try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, bch);
ps.setInt(2, blockNumber);
ps.setBytes(3, blockHash);
try (ResultSet rs = ps.executeQuery()) {
return rs.next() ? rs.getInt("cnt") : 0;
}
}
}
static boolean isSeenByLogin(Connection c, String login, String toBch, int toBlockNumber, byte[] toBlockHash) throws SQLException {
if (login == null || login.isBlank() || toBch == null || toBch.isBlank() || toBlockHash == null || toBlockHash.length != 32) {
return false;
}
String sql = """
SELECT 1
FROM message_views_state
WHERE viewer_login = ? COLLATE NOCASE
AND to_bch_name = ?
AND to_block_number = ?
AND to_block_hash = ?
LIMIT 1
""";
try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, login);
ps.setString(2, toBch);
ps.setInt(3, toBlockNumber);
ps.setBytes(4, toBlockHash);
try (ResultSet rs = ps.executeQuery()) {
return rs.next();
}
}
}
static int countUnreadPosts(Connection c, String viewerLogin, String ownerBch, int lineCode) throws SQLException {
if (viewerLogin == null || viewerLogin.isBlank() || ownerBch == null || ownerBch.isBlank() || lineCode < 0) return 0;
String sql = """
SELECT COUNT(*) AS cnt
FROM blocks b
LEFT JOIN message_views_state v
ON v.viewer_login = ?
AND v.to_bch_name = b.bch_name
AND v.to_block_number = b.block_number
AND v.to_block_hash = b.block_hash
WHERE b.bch_name = ?
AND b.msg_type = ?
AND b.msg_sub_type = ?
AND b.line_code = ?
AND v.viewer_login IS NULL
""";
try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, viewerLogin);
ps.setString(2, ownerBch);
ps.setInt(3, MSG_TYPE_TEXT);
ps.setInt(4, MsgSubType.TEXT_POST);
ps.setInt(5, lineCode);
try (ResultSet rs = ps.executeQuery()) {
return rs.next() ? rs.getInt("cnt") : 0;
}
}
}
static PostBlock firstUnreadPost(Connection c, String viewerLogin, String ownerBch, int lineCode) throws SQLException {
if (viewerLogin == null || viewerLogin.isBlank() || ownerBch == null || ownerBch.isBlank() || lineCode < 0) return null;
String sql = """
SELECT b.login,b.bch_name,b.block_number,b.block_hash,b.block_bytes
FROM blocks b
LEFT JOIN message_views_state v
ON v.viewer_login = ?
AND v.to_bch_name = b.bch_name
AND v.to_block_number = b.block_number
AND v.to_block_hash = b.block_hash
WHERE b.bch_name = ?
AND b.msg_type = ?
AND b.msg_sub_type = ?
AND b.line_code = ?
AND v.viewer_login IS NULL
ORDER BY b.block_number ASC
LIMIT 1
""";
try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, viewerLogin);
ps.setString(2, ownerBch);
ps.setInt(3, MSG_TYPE_TEXT);
ps.setInt(4, MsgSubType.TEXT_POST);
ps.setInt(5, lineCode);
try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) return null;
PostBlock pb = new PostBlock();
pb.login = rs.getString("login");
pb.bchName = rs.getString("bch_name");
pb.blockNumber = rs.getInt("block_number");
pb.blockHash = rs.getBytes("block_hash");
pb.blockBytes = rs.getBytes("block_bytes");
return pb;
}
}
}
static String detectChannelDescription(Connection c, String ownerBch, int rootNumber) throws SQLException {
if (rootNumber == 0) return "";
@@ -108,22 +108,11 @@ public class Net_GetChannelMessages_Handler implements JsonMessageHandler {
item.setLikesCount(stats[0]);
item.setRepliesCount(stats[1]);
item.setLikedByMe(ChannelsReadSupport.isLikedByLogin(c, viewerLogin, post.bchName, post.blockNumber, post.blockHash));
item.setViewCount(ChannelsReadSupport.countViews(c, post.bchName, post.blockNumber, post.blockHash));
item.setSeenByMe(ChannelsReadSupport.isSeenByLogin(c, viewerLogin, post.bchName, post.blockNumber, post.blockHash));
items.add(item);
}
resp.setMessages(items);
int unreadCount = ChannelsReadSupport.countUnreadPosts(c, viewerLogin, ownerBch, lineCode);
resp.setUnreadCount(unreadCount);
ChannelsReadSupport.PostBlock firstUnread = ChannelsReadSupport.firstUnreadPost(c, viewerLogin, ownerBch, lineCode);
if (firstUnread != null) {
Net_GetChannelMessages_Response.BlockRef firstUnreadRef = new Net_GetChannelMessages_Response.BlockRef();
firstUnreadRef.setBlockNumber(firstUnread.blockNumber);
firstUnreadRef.setBlockHash(ChannelsReadSupport.toHex(firstUnread.blockHash));
resp.setFirstUnreadMessageRef(firstUnreadRef);
}
return resp;
} catch (Exception e) {
log.error("GetChannelMessages failed", e);
@@ -178,9 +178,6 @@ public class Net_GetMessageThread_Handler implements JsonMessageHandler {
node.setLikesCount(stats[0]);
node.setRepliesCount(stats[1]);
node.setLikedByMe(ChannelsReadSupport.isLikedByLogin(c, viewerLogin, row.bchName, row.blockNumber, row.blockHash));
node.setViewCount(ChannelsReadSupport.countViews(c, row.bchName, row.blockNumber, row.blockHash));
node.setSeenByMe(ChannelsReadSupport.isSeenByLogin(c, viewerLogin, row.bchName, row.blockNumber, row.blockHash));
if (row.lineCode != null && row.lineCode >= 0) {
Net_GetMessageThread_Response.ChannelInfo ci = new Net_GetMessageThread_Response.ChannelInfo();
ci.setOwnerBlockchainName(row.bchName);
@@ -229,4 +226,3 @@ public class Net_GetMessageThread_Handler implements JsonMessageHandler {
int msgSubType;
}
}
@@ -74,7 +74,7 @@ public class Net_ListSubscriptionsFeed_Handler implements JsonMessageHandler {
row.setChannel(channelRef);
row.setMessagesCount(ChannelsReadSupport.countPosts(c, key.ownerBch, key.rootNumber));
row.setUnreadCount(ChannelsReadSupport.countUnreadPosts(c, viewerLogin, key.ownerBch, key.rootNumber));
row.setUnreadCount(0);
ChannelsReadSupport.PostBlock lastPost = ChannelsReadSupport.loadLastPost(c, key.ownerBch, key.rootNumber);
if (lastPost != null) {
@@ -8,8 +8,6 @@ import java.util.List;
public class Net_GetChannelMessages_Response extends Net_Response {
private Channel channel;
private List<MessageItem> messages = new ArrayList<>();
private int unreadCount;
private BlockRef firstUnreadMessageRef;
public Channel getChannel() { return channel; }
public void setChannel(Channel channel) { this.channel = channel; }
@@ -17,11 +15,6 @@ public class Net_GetChannelMessages_Response extends Net_Response {
public List<MessageItem> getMessages() { return messages; }
public void setMessages(List<MessageItem> messages) { this.messages = messages; }
public int getUnreadCount() { return unreadCount; }
public void setUnreadCount(int unreadCount) { this.unreadCount = unreadCount; }
public BlockRef getFirstUnreadMessageRef() { return firstUnreadMessageRef; }
public void setFirstUnreadMessageRef(BlockRef firstUnreadMessageRef) { this.firstUnreadMessageRef = firstUnreadMessageRef; }
public static class Channel {
private String ownerLogin;
@@ -55,8 +48,6 @@ public class Net_GetChannelMessages_Response extends Net_Response {
private int likesCount;
private boolean likedByMe;
private int repliesCount;
private int viewCount;
private boolean seenByMe;
private int versionsTotal;
private List<VersionItem> versions = new ArrayList<>();
@@ -84,12 +75,6 @@ public class Net_GetChannelMessages_Response extends Net_Response {
public int getRepliesCount() { return repliesCount; }
public void setRepliesCount(int repliesCount) { this.repliesCount = repliesCount; }
public int getViewCount() { return viewCount; }
public void setViewCount(int viewCount) { this.viewCount = viewCount; }
public boolean isSeenByMe() { return seenByMe; }
public void setSeenByMe(boolean seenByMe) { this.seenByMe = seenByMe; }
public int getVersionsTotal() { return versionsTotal; }
public void setVersionsTotal(int versionsTotal) { this.versionsTotal = versionsTotal; }