New binary log format, with color/face support
Binary logs are no longer stored as a single message with a list of strings and int64s ("body", "user_name", "user_id", "when"), but a message with sub-messages (IM_MESSAGE_RECEIVED) verbatim saved. This has the main benefit of preserving message formatting (coloring, bold, italics, etc).
This commit is contained in:
parent
5aeaf9284f
commit
8512e9ad03
|
@ -76,9 +76,8 @@ enum im_what_code {
|
|||
If chat_id is ommitted, the message is sent to the protocol's system
|
||||
buffer, rather than a specific conversation.
|
||||
face_start and face_length specify the location of formatted text in
|
||||
the body, and "face" is the desired font face. Unsupported in bulk,
|
||||
the body, and "face" is the desired font face.
|
||||
color_* works much the same, but with colors. Not much else to say.
|
||||
i.e., IM_LOGS_RECEIVED.
|
||||
Requires: String "body"
|
||||
Allows: String "chat_id", String "user_id", String "user_name",
|
||||
int32s "face_start", int32s "face_length", uint16s "face"
|
||||
|
@ -87,9 +86,8 @@ enum im_what_code {
|
|||
IM_MESSAGE_RECEIVED = 22,
|
||||
|
||||
/*! Logs received →App
|
||||
Without "when" (a time_t), the logged message will lack a timestamp
|
||||
Requires: Strings "chat_id", Strings "user_id", Strings "body"
|
||||
Accepts: in64s "when" */
|
||||
Should be a message with several sub-messages of IM_MESSAGE_RECEIVED.
|
||||
Requires: Messages "message" */
|
||||
IM_LOGS_RECEIVED = 23,
|
||||
|
||||
|
||||
|
|
|
@ -123,7 +123,6 @@ Conversation::ImMessage(BMessage* msg)
|
|||
if (icon == NULL)
|
||||
icon = ProtocolBitmap();
|
||||
|
||||
|
||||
BNotification notification(B_INFORMATION_NOTIFICATION);
|
||||
notification.SetGroup(BString(APP_NAME));
|
||||
notification.SetTitle(notifyTitle);
|
||||
|
@ -402,7 +401,6 @@ Conversation::GetView()
|
|||
BMessage logMsg;
|
||||
if (_GetChatLogs(&logMsg) == B_OK)
|
||||
fChatView->MessageReceived(&logMsg);
|
||||
|
||||
return fChatView;
|
||||
}
|
||||
|
||||
|
@ -499,66 +497,42 @@ Conversation::_WarnUser(BString message)
|
|||
void
|
||||
Conversation::_LogChatMessage(BMessage* msg)
|
||||
{
|
||||
// Binary logs
|
||||
// TODO: Don't hardcode 31, expose maximum as a setting
|
||||
const int32 MAX = 31;
|
||||
|
||||
BMessage logMsg(IM_MESSAGE);
|
||||
if (_GetChatLogs(&logMsg) != B_OK) {
|
||||
logMsg.what = IM_MESSAGE;
|
||||
logMsg.AddInt32("im_what", IM_LOGS_RECEIVED);
|
||||
}
|
||||
|
||||
BMessage last;
|
||||
if (logMsg.FindMessage("message", MAX, &last) == B_OK)
|
||||
logMsg.RemoveData("message", 0);
|
||||
msg->AddInt64("when", time(NULL));
|
||||
logMsg.AddMessage("message", msg);
|
||||
|
||||
BFile logFile(fCachePath.Path(), B_READ_WRITE | B_OPEN_AT_END | B_CREATE_FILE);
|
||||
WriteAttributeMessage(&logFile, "Chat:logs", &logMsg);
|
||||
|
||||
// Plain-text logs
|
||||
// Gotta make sure the formatting's pretty!
|
||||
BString date;
|
||||
fDateFormatter.Format(date, time(0), B_SHORT_DATE_FORMAT, B_MEDIUM_TIME_FORMAT);
|
||||
|
||||
BString id = msg->FindString("user_id");
|
||||
BString name = msg->FindString("user_name");
|
||||
BString body = msg->FindString("body");
|
||||
|
||||
if (id.IsEmpty() == true)
|
||||
if (id.IsEmpty() == true && name.IsEmpty() == true)
|
||||
return;
|
||||
|
||||
if (name.IsEmpty() == true) {
|
||||
else if (name.IsEmpty() == true) {
|
||||
User* user = UserById(id);
|
||||
if (user == NULL)
|
||||
name = id;
|
||||
else
|
||||
name = user->GetName();
|
||||
name = user ? user->GetName() : id;
|
||||
}
|
||||
|
||||
// Binary logs
|
||||
// TODO: Don't hardcode 31, expose maximum as a setting
|
||||
int32 max = 31;
|
||||
BStringList user_ids, user_names, bodies;
|
||||
int64 times[max] = { 0 };
|
||||
times[0] = (int64)time(NULL);
|
||||
|
||||
BMessage logMsg;
|
||||
if (_GetChatLogs(&logMsg) == B_OK) {
|
||||
logMsg.FindStrings("body", &bodies);
|
||||
logMsg.FindStrings("user_id", &user_ids);
|
||||
logMsg.FindStrings("user_name", &user_names);
|
||||
|
||||
int64 found;
|
||||
for (int i = 0; i < max; i++)
|
||||
if (logMsg.FindInt64("when", i, &found) == B_OK)
|
||||
times[i + 1] = found;
|
||||
|
||||
bodies.Remove(max);
|
||||
user_ids.Remove(max);
|
||||
user_names.Remove(max);
|
||||
bodies.Add(body, 0);
|
||||
user_ids.Add(id, 0);
|
||||
user_names.Add(name, 0);
|
||||
}
|
||||
|
||||
BMessage newLogMsg(IM_MESSAGE);
|
||||
newLogMsg.AddInt32("im_what", IM_LOGS_RECEIVED);
|
||||
newLogMsg.AddStrings("body", bodies);
|
||||
newLogMsg.AddStrings("user_id", user_ids);
|
||||
newLogMsg.AddStrings("user_name", user_names);
|
||||
newLogMsg.AddInt64("when", time(NULL));
|
||||
for (int i = 0; i < max; i++)
|
||||
newLogMsg.AddInt64("when", times[i]);
|
||||
|
||||
BFile logFile(fCachePath.Path(), B_READ_WRITE | B_OPEN_AT_END | B_CREATE_FILE);
|
||||
WriteAttributeMessage(&logFile, "Chat:logs", &newLogMsg);
|
||||
|
||||
// Plain-text logs
|
||||
BString logLine("[");
|
||||
logLine << date << "] <" << name << "> " << body << "\n";
|
||||
|
||||
logFile.Write(logLine.String(), logLine.Length());
|
||||
}
|
||||
|
||||
|
@ -567,9 +541,7 @@ status_t
|
|||
Conversation::_GetChatLogs(BMessage* msg)
|
||||
{
|
||||
_EnsureCachePath();
|
||||
|
||||
BFile logFile(fCachePath.Path(), B_READ_WRITE | B_CREATE_FILE);
|
||||
|
||||
return ReadAttributeMessage(&logFile, "Chat:logs", msg);
|
||||
}
|
||||
|
||||
|
@ -581,7 +553,6 @@ Conversation::_CacheRoomFlags()
|
|||
BFile cacheFile(fCachePath.Path(), B_READ_WRITE | B_CREATE_FILE);
|
||||
if (cacheFile.InitCheck() != B_OK)
|
||||
return;
|
||||
|
||||
cacheFile.WriteAttr("Chat:flags", B_INT32_TYPE, 0, &fRoomFlags, sizeof(int32));
|
||||
}
|
||||
|
||||
|
@ -593,7 +564,6 @@ Conversation::_LoadRoomFlags()
|
|||
BFile cacheFile(fCachePath.Path(), B_READ_ONLY);
|
||||
if (cacheFile.InitCheck() != B_OK)
|
||||
return;
|
||||
|
||||
cacheFile.ReadAttr("Chat:flags", B_INT32_TYPE, 0, &fRoomFlags, sizeof(int32));
|
||||
}
|
||||
|
||||
|
|
|
@ -393,6 +393,15 @@ ConversationView::_AppendOrEnqueueMessage(BMessage* msg)
|
|||
// later [AttachedToWindow()], since you can't edit an unattached
|
||||
// RenderView.
|
||||
if (Window() == NULL) {
|
||||
// If contains multiple chat messages (e.g., IM_LOGS_RECEIVED), add all
|
||||
int32 i = -1;
|
||||
BMessage text;
|
||||
while (msg->FindMessage("message", i + 1, &text) == B_OK) {
|
||||
fMessageQueue.AddItem(new BMessage(text));
|
||||
i++;
|
||||
}
|
||||
// Else, add the lonely, lonely, single-messaged one
|
||||
if (i == -1)
|
||||
fMessageQueue.AddItem(new BMessage(*msg));
|
||||
return false;
|
||||
}
|
||||
|
@ -412,62 +421,7 @@ ConversationView::_AppendMessage(BMessage* msg)
|
|||
return;
|
||||
}
|
||||
|
||||
// … else we're jamming a message into this view no matter what it takes!
|
||||
if (msg->HasInt32("face_start") || msg->HasInt32("color_start")) {
|
||||
_AppendFormattedMessage(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
// For unformatted (normal or bulk) messages
|
||||
BStringList user_ids, user_names, bodies;
|
||||
if (msg->FindStrings("body", &bodies) != B_OK)
|
||||
return;
|
||||
msg->FindStrings("user_id", &user_ids);
|
||||
msg->FindStrings("user_name", &user_names);
|
||||
|
||||
for (int i = bodies.CountStrings(); i >= 0; i--) {
|
||||
User* sender = NULL;
|
||||
if (fConversation != NULL)
|
||||
sender = fConversation->UserById(user_ids.StringAt(i));
|
||||
BString sender_id = user_ids.StringAt(i);
|
||||
BString sender_name = user_names.StringAt(i);
|
||||
BString body = bodies.StringAt(i);
|
||||
rgb_color userColor = ui_color(B_PANEL_TEXT_COLOR);
|
||||
int64 timeInt;
|
||||
|
||||
if (msg->FindInt64("when", i, &timeInt) != B_OK)
|
||||
timeInt = (int64)time(NULL);
|
||||
|
||||
if (sender != NULL) {
|
||||
sender_name = sender->GetName();
|
||||
userColor = sender->fItemColor;
|
||||
}
|
||||
|
||||
if (sender_name.IsEmpty() == true && sender_id.IsEmpty() == false)
|
||||
sender_name = sender_id;
|
||||
|
||||
if (sender_id.IsEmpty() == true && sender_name.IsEmpty() == true) {
|
||||
fReceiveView->AppendGeneric(body.String());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (body.StartsWith("/me ")) {
|
||||
BString meMsg = "** ";
|
||||
meMsg << sender_name.String() << " ";
|
||||
meMsg << body.RemoveFirst("/me ");
|
||||
fReceiveView->AppendGeneric(meMsg.String());
|
||||
continue;
|
||||
}
|
||||
|
||||
fReceiveView->AppendMessage(sender_name.String(), body.String(),
|
||||
userColor, (time_t)timeInt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConversationView::_AppendFormattedMessage(BMessage* msg)
|
||||
{
|
||||
// Otherwise, it's message time!
|
||||
int64 timeInt;
|
||||
BString user_id;
|
||||
BString user_name = msg->FindString("user_name");
|
||||
|
@ -496,6 +450,13 @@ ConversationView::_AppendFormattedMessage(BMessage* msg)
|
|||
return;
|
||||
}
|
||||
|
||||
if (body.StartsWith("/me ")) {
|
||||
BString meMsg = "** ";
|
||||
meMsg << user_name.String() << " ";
|
||||
meMsg << body.RemoveFirst("/me ");
|
||||
fReceiveView->AppendGeneric(meMsg.String());
|
||||
return;
|
||||
}
|
||||
|
||||
fReceiveView->AppendTimestamp(timeInt);
|
||||
fReceiveView->AppendUserstamp(user_name, userColor);
|
||||
|
|
|
@ -57,7 +57,6 @@ private:
|
|||
|
||||
bool _AppendOrEnqueueMessage(BMessage* msg);
|
||||
void _AppendMessage(BMessage* msg);
|
||||
void _AppendFormattedMessage(BMessage* msg);
|
||||
|
||||
// Helper functions for _AppendFormattedMessage()
|
||||
void _EnableStartingFaces(BMessage* msg, int32 index,
|
||||
|
|
Ŝarĝante…
Reference in New Issue