Ensure unique timestamps for chat messages to prevent collisions and fix date formatting in chat-box UI.
This commit is contained in:
parent
564582a6f9
commit
9e5148fa8c
|
|
@ -2,6 +2,7 @@ package com.alttd.altitudeweb.controllers.chat;
|
|||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
|
@ -11,7 +12,8 @@ import java.util.UUID;
|
|||
public class ChatMessage {
|
||||
|
||||
private final UUID uuid;
|
||||
private final Instant timestamp;
|
||||
@Setter
|
||||
private Instant timestamp;
|
||||
private final String server;
|
||||
//TODO [Stijn] [2026-07-18]: Handle channel types
|
||||
//private final String channel;
|
||||
|
|
|
|||
|
|
@ -4,16 +4,18 @@ import com.alttd.altitudeweb.database.chat.ChatLogDao;
|
|||
import com.alttd.altitudeweb.model.ChatMessageDto;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
@UtilityClass
|
||||
public class ChatMessageMapper {
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
|
||||
.registerModule(new JavaTimeModule());
|
||||
.registerModule(new JavaTimeModule())
|
||||
.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
|
||||
|
||||
public ChatMessage fromDto(ChatMessageDto dto) {
|
||||
return ChatMessage.builder()
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ public class ChatService {
|
|||
private String[] allowedServers;
|
||||
private final NavigableMap<Instant, ChatMessage> chatMessages = new TreeMap<>();
|
||||
private final EventPublisher eventPublisher;
|
||||
private long lastMillis = 0;
|
||||
|
||||
@Scheduled(cron = "0 * * * * *")
|
||||
public void clearOldMessages() {
|
||||
|
|
@ -50,7 +51,8 @@ public class ChatService {
|
|||
try {
|
||||
sqlSession.getMapper(ChatLogMapper.class)
|
||||
.getChatLogs(Instant.now().minus(Duration.ofHours(1)).toEpochMilli())
|
||||
.stream().map(ChatMessageMapper::fromDao)
|
||||
.stream()
|
||||
.map(ChatMessageMapper::fromDao)
|
||||
.forEach(this::putChatMessage);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to load history count", e);
|
||||
|
|
@ -58,7 +60,19 @@ public class ChatService {
|
|||
});
|
||||
}
|
||||
|
||||
private synchronized void setUniqueTimestamp(ChatMessage chatMessage) {
|
||||
long timestamp = chatMessage.getTimestamp().toEpochMilli();
|
||||
if (timestamp == lastMillis) {
|
||||
timestamp += 1;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
lastMillis = timestamp;
|
||||
chatMessage.setTimestamp(Instant.ofEpochMilli(timestamp));
|
||||
}
|
||||
|
||||
private void putChatMessage(ChatMessage chatMessage) {
|
||||
setUniqueTimestamp(chatMessage);
|
||||
chatMessages.put(chatMessage.getTimestamp(), chatMessage);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
@for (message of messages(); track message.timestamp) {
|
||||
<p class="message">
|
||||
<span class="date-time" [class.blocked]="!message.notBlocked">
|
||||
[{{ message.timestamp * 1000 | date: 'mediumTime' }}]
|
||||
[{{ message.timestamp | date: 'mediumTime' }}]
|
||||
</span>
|
||||
<mini-message [node]="message.messageJson"></mini-message>
|
||||
</p>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user