Keep every line of a multi-line message in chat history
The text log has a message's line breaks in it, but history was read one line at a time, so every line after the first failed to parse and was dropped. A line that starts no entry of its own now continues the message before it, which also recovers what earlier versions wrote. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -175,13 +175,33 @@ public final class ChatLogStore {
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* A message is written as it was sent, so one with line breaks spans several lines of the
|
||||
* log: a line that starts no entry of its own continues the message before it.
|
||||
*/
|
||||
private static List<String> readTextMessages(LogFiles files, ChatLogScope scope) throws IOException {
|
||||
if (!Files.isRegularFile(files.txt)) return Collections.emptyList();
|
||||
List<String> entries = new ArrayList<>();
|
||||
Matcher message = null;
|
||||
StringBuilder text = new StringBuilder();
|
||||
for (String line : Files.readAllLines(files.txt, StandardCharsets.UTF_8)) {
|
||||
String entry = textLineToHtml(line, scope);
|
||||
if (entry != null) entries.add(entry);
|
||||
Matcher m = TEXT_MESSAGE.matcher(line);
|
||||
boolean begin = line.startsWith("*** ");
|
||||
if (!m.matches() && !begin) {
|
||||
if (message != null) text.append('\n').append(line);
|
||||
continue;
|
||||
}
|
||||
if (message != null) entries.add(messageLineHtml(message, text, scope));
|
||||
message = null;
|
||||
if (begin) {
|
||||
entries.add(beginLineHtml(line));
|
||||
} else {
|
||||
message = m;
|
||||
text.setLength(0);
|
||||
text.append(m.group(3));
|
||||
}
|
||||
}
|
||||
if (message != null) entries.add(messageLineHtml(message, text, scope));
|
||||
return entries;
|
||||
}
|
||||
|
||||
@@ -190,14 +210,12 @@ public final class ChatLogStore {
|
||||
return new ArrayList<>(entries.subList(entries.size() - limit, entries.size()));
|
||||
}
|
||||
|
||||
private static String textLineToHtml(String line, ChatLogScope scope) {
|
||||
if (line == null || line.isBlank()) return null;
|
||||
if (line.startsWith("*** ")) {
|
||||
return "<div class=\"TextMessage_BeginHistory\"><span class=\"Body\">"
|
||||
+ BBCode.escape(line) + "</span></div>";
|
||||
}
|
||||
Matcher m = TEXT_MESSAGE.matcher(line);
|
||||
if (!m.matches()) return null;
|
||||
private static String beginLineHtml(String line) {
|
||||
return "<div class=\"TextMessage_BeginHistory\"><span class=\"Body\">"
|
||||
+ BBCode.escape(line) + "</span></div>";
|
||||
}
|
||||
|
||||
private static String messageLineHtml(Matcher m, CharSequence text, ChatLogScope scope) {
|
||||
String target = switch (scope) {
|
||||
case PRIVATE -> "Private";
|
||||
case CHANNEL -> "Channel";
|
||||
@@ -206,7 +224,8 @@ public final class ChatLogStore {
|
||||
return "<div class=\"TextMessage_Message Incoming Neutral " + target + "\"><span class=\"Body\">"
|
||||
+ "<span class=\"TextMessage_Time\"><" + m.group(1) + "></span> "
|
||||
+ "<span class=\"TextMessage_UserLink\">"" + BBCode.escape(m.group(2)) + ""</span>: "
|
||||
+ "<span class=\"TextMessage_Text\">" + BBCode.toHtml(m.group(3)) + "</span></span></div>";
|
||||
+ "<span class=\"TextMessage_Text\">" + BBCode.toHtml(text.toString().stripTrailing())
|
||||
+ "</span></span></div>";
|
||||
}
|
||||
|
||||
private static String beginHtml(String kind, LocalDateTime timestamp) {
|
||||
|
||||
@@ -68,4 +68,16 @@ class ChatLogStoreTest {
|
||||
assertTrue(capped.truncated());
|
||||
assertTrue(capped.entries().get(9).contains("filler " + (ChatLogStore.HISTORY_LIMIT - 1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void readsAMessageWithLineBreaksBackWhole() throws Exception {
|
||||
ChatLogStore logs = new ChatLogStore(temp, "+Tyg2JtxE8vRNZp+JiUBnmBh0MY=");
|
||||
logs.appendMessage(ChatLogScope.CHANNEL, false, 5, "uid", "alice", "first line\n\nthird line");
|
||||
logs.appendMessage(ChatLogScope.CHANNEL, false, 5, "uid", "bob", "reply");
|
||||
|
||||
List<String> history = logs.channelHtmlHistory();
|
||||
assertEquals(2, history.size());
|
||||
assertTrue(history.get(0).contains("first line<br><br>third line"), history.get(0));
|
||||
assertTrue(history.get(1).contains("reply"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user