From d8d89d245e2b3f36d8b2d7723c9b1b7c5f90bc44 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Thu, 19 Aug 2021 00:59:03 -0500 Subject: [PATCH] Toggling of room flags through right-click menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Room flags (e.g., whether or not to auto-join, whether notifications should be sent on message receive) can now be toggled through a room's right-click menu in the room-list. Two new room flags were added for notifications as well― ROOM_NOTIFY_DM and ROOM_NOTIFY_ALL. If ROOM_NOTIFY_DM is enabled, the user will receive notifications if they are in a one-on-one chat. If ROOM_NOTIFY_ALL, they will receive notifications on every message sent to the room. The default menu items for the room's pop-up menu were moved from Templates.rdef to be built into the app. Everything else in Templates.rdef should follow suit― B_TRANSLATE can't be used in rdef files! --- application/AppMessages.h | 3 + application/ChatProtocolMessages.h | 3 +- application/Conversation.cpp | 54 +++++++++++------- application/Conversation.h | 4 +- application/Flags.h | 7 ++- application/Server.cpp | 31 +++++------ application/Server.h | 2 - application/views/ConversationListView.cpp | 64 +++++++++++++++++++++- application/views/ConversationListView.h | 1 + data/misc/Templates.rdef | 17 ------ 10 files changed, 121 insertions(+), 65 deletions(-) diff --git a/application/AppMessages.h b/application/AppMessages.h index 4047c53..fc7a210 100644 --- a/application/AppMessages.h +++ b/application/AppMessages.h @@ -59,6 +59,9 @@ const uint32 APP_USER_INFO = 'CYuw'; //! Display a "room info" window const uint32 APP_ROOM_INFO = 'CYrw'; +//! Toggle a specific flag for a room +const uint32 APP_ROOM_FLAG = 'Rlag'; + //! Edit the contact roster const uint32 APP_EDIT_ROSTER = 'CYer'; diff --git a/application/ChatProtocolMessages.h b/application/ChatProtocolMessages.h index 63e5d34..ec2d657 100644 --- a/application/ChatProtocolMessages.h +++ b/application/ChatProtocolMessages.h @@ -317,7 +317,8 @@ enum im_what_code { Recommendations on default room flags: Unless your protocol has remote logs, ROOM_LOG_LOCALLY and ROOM_POPULATE_LOGS should be enabled; and for multi-user rooms, ROOM_AUTOJOIN should be enabled by default (again, - unless the protocol manages auto-joins). + unless the protocol manages auto-joins). ROOM_NOTIFY_DM should be + enabled by default for all rooms― ROOM_NOTIFY_ALL should be off. Requires: String "chat_id" Allows: String "chat_name", String "subject", int32 "room_default_flags", int32 "room_disallowed_flags" */ diff --git a/application/Conversation.cpp b/application/Conversation.cpp index a12e8f7..f81687a 100644 --- a/application/Conversation.cpp +++ b/application/Conversation.cpp @@ -90,31 +90,31 @@ Conversation::ImMessage(BMessage* msg) Contact* contact = GetOwnContact(); BWindow* win = fChatView->Window(); - bool winFocused = (win != NULL && + bool winFocus = (win != NULL && (win->IsFront() && !(win->IsMinimized()))); bool mentioned = ((contact->GetName().IsEmpty() == false && text.IFindFirst(contact->GetName()) != B_ERROR) || (text.IFindFirst(contact->GetId()) != B_ERROR)); // Sound the bell, if appropriate - if (mentioned == true && winFocused == false - && AppPreferences::Get()->SoundOnMention == true) - system_beep(APP_MENTION_BEEP); - else if (winFocused == false && (fUsers.CountItems() <= 2) - && AppPreferences::Get()->SoundOnMessageReceived == true) - system_beep(APP_MESSAGE_BEEP); + if (winFocus == false) { + if (mentioned == true + && AppPreferences::Get()->SoundOnMention == true) + system_beep(APP_MENTION_BEEP); + else if (AppPreferences::Get()->SoundOnMessageReceived == true + && ((fUsers.CountItems() <=2 && (fRoomFlags & ROOM_NOTIFY_DM)) + || (fRoomFlags & ROOM_NOTIFY_ALL))) + system_beep(APP_MESSAGE_BEEP); + } // Send a notification, if appropriate - if (winFocused == false && AppPreferences::Get()->NotifyNewMessage - && (fUsers.CountItems() <= 2 || mentioned == true)) - { + if (winFocus == false && AppPreferences::Get()->NotifyNewMessage) { BString notifyTitle = B_TRANSLATE("New mention"); BString notifyText = B_TRANSLATE("You've been summoned from " "%source%."); if (mentioned == false) { fNotifyMessageCount++; - notifyTitle.SetTo(B_TRANSLATE("New message")); notifyText.SetTo(""); @@ -128,17 +128,21 @@ Conversation::ImMessage(BMessage* msg) notifyText.ReplaceAll("%source%", GetName()); - BBitmap* icon = IconBitmap(); - if (icon == NULL) - icon = ProtocolBitmap(); + if ((fUsers.CountItems() <= 2 && (fRoomFlags & ROOM_NOTIFY_DM)) + || (fRoomFlags & ROOM_NOTIFY_ALL) || mentioned == true) + { + BBitmap* icon = IconBitmap(); + if (icon == NULL) + icon = ProtocolBitmap(); - BNotification notification(B_INFORMATION_NOTIFICATION); - notification.SetGroup(BString(APP_NAME)); - notification.SetTitle(notifyTitle); - notification.SetIcon(icon); - notification.SetContent(notifyText); - notification.SetMessageID(fID); - notification.Send(); + BNotification notification(B_INFORMATION_NOTIFICATION); + notification.SetGroup(BString(APP_NAME)); + notification.SetTitle(notifyTitle); + notification.SetIcon(icon); + notification.SetContent(notifyText); + notification.SetMessageID(fID); + notification.Send(); + } } // If unattached, highlight the ConversationItem @@ -520,6 +524,14 @@ Conversation::GetRole(BString id) } +void +Conversation::SetFlags(int32 flags) +{ + fRoomFlags = flags; + _CacheRoomFlags(); +} + + void Conversation::_WarnUser(BString message) { diff --git a/application/Conversation.h b/application/Conversation.h index 2fd52a4..28d07c3 100644 --- a/application/Conversation.h +++ b/application/Conversation.h @@ -72,7 +72,9 @@ public: void SetRole(BString id, Role* role); Role* GetRole(BString id); - int32 GetFlags(int32 flags) { return fRoomFlags; } + int32 GetFlags() { return fRoomFlags; } + void SetFlags(int32 flags); + int32 DisallowedFlags() { return fDisallowedFlags; } private: void _WarnUser(BString message); diff --git a/application/Flags.h b/application/Flags.h index 54aa8bf..fed79ec 100644 --- a/application/Flags.h +++ b/application/Flags.h @@ -5,9 +5,10 @@ #ifndef FLAGS_H #define FLAGS_H -// AUTOJOIN, AUTOCREATE, LOG, POPULATE +// AUTOJOIN, AUTOCREATE, LOG, POPULATE, NOTIFY // Auto-join on login, auto-create on login (non-persistent rooms), keep local -// logs, populate chat with local logs on join… +// logs, populate chat with local logs on join, notify on direct message, +// notify on all new messages… // JCLP // 0000 @@ -16,6 +17,8 @@ #define ROOM_AUTOCREATE 2 #define ROOM_LOG_LOCALLY 4 #define ROOM_POPULATE_LOGS 8 +#define ROOM_NOTIFY_DM 16 +#define ROOM_NOTIFY_ALL 32 // NAME, SUBJECT, ROLECHANGE, BAN, KICK, DEAFEN, MUTE, NICK, READ, WRITE diff --git a/application/Server.cpp b/application/Server.cpp index 4e2f5b6..5f7eb41 100644 --- a/application/Server.cpp +++ b/application/Server.cpp @@ -53,8 +53,7 @@ Server::Server() : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE) { - if (fChatItems.IsEmpty() == false || fUserItems.IsEmpty() == false - || fCommands.CountItems() > 0) + if (fUserItems.IsEmpty() == false || fCommands.CountItems() > 0) return; BResources res = ChatResources(); @@ -70,15 +69,6 @@ Server::Server() fUserItems.AddItem(new BMessage(temp)); } - // Loading room pop-up items - for (int i = 0; i < 2; i++) { - size_t size; - BMessage temp; - const void* buff = res.LoadResource(B_MESSAGE_TYPE, 1120 + i, &size); - temp.Unflatten((const char*)buff); - fChatItems.AddItem(new BMessage(temp)); - } - // Loading default chat commands for (int i = 0; i < 9; i++) { size_t size; @@ -186,6 +176,18 @@ Server::Filter(BMessage* message, BHandler **target) } break; } + case APP_ROOM_FLAG: + { + int32 flag; + Conversation* chat = _EnsureConversation(message); + if (chat == NULL || message->FindInt32("flag", &flag) != B_OK) + break; + + int32 flags = chat->GetFlags(); + flags ^= flag; + chat->SetFlags(flags); + break; + } case APP_USER_INFO: { User* user = _EnsureUser(message); @@ -925,13 +927,6 @@ Server::CommandById(BString id, int64 instance) } -BObjectList -Server::ChatPopUpItems() -{ - return fChatItems; -} - - BObjectList Server::UserPopUpItems() { diff --git a/application/Server.h b/application/Server.h index 91c577b..73958fb 100644 --- a/application/Server.h +++ b/application/Server.h @@ -67,7 +67,6 @@ public: CommandMap Commands(int64 instance); ChatCommand* CommandById(BString id, int64 instance); - BObjectList ChatPopUpItems(); BObjectList UserPopUpItems(); private: @@ -94,7 +93,6 @@ private: bool fStarted; CommandMap fCommands; - BObjectList fChatItems; BObjectList fUserItems; }; diff --git a/application/views/ConversationListView.cpp b/application/views/ConversationListView.cpp index ab4b9f8..d574786 100644 --- a/application/views/ConversationListView.cpp +++ b/application/views/ConversationListView.cpp @@ -206,6 +206,7 @@ BPopUpMenu* ConversationListView::_ConversationPopUp() { BPopUpMenu* menu = new BPopUpMenu("chatPopUp"); + menu->SetRadioMode(false); int32 selIndex = CurrentSelection(); ConversationItem* item; @@ -215,9 +216,11 @@ ConversationListView::_ConversationPopUp() ProtocolLooper* looper = chat->GetProtocolLooper(); Server* server = ((TheApp*)be_app)->GetMainWindow()->GetServer(); - BObjectList items = server->ChatPopUpItems(); - BObjectList protoItems = looper->Protocol()->ChatPopUpItems(); - items.AddList(&protoItems); + _AddDefaultItems(menu, chat); + BObjectList items = looper->Protocol()->ChatPopUpItems(); + + if (items.CountItems() > 0) + menu->AddSeparatorItem(); for (int i = 0; i < items.CountItems(); i++) { BMessage* itemMsg = items.ItemAt(i); @@ -239,6 +242,61 @@ ConversationListView::_ConversationPopUp() } +#define add_flag_item(name, flag) { \ + msg = new BMessage(APP_ROOM_FLAG); \ + msg->AddString("chat_id", id); \ + msg->AddInt64("instance", instance); \ + msg->AddInt32("flag", flag); \ +\ + item = new BMenuItem(name, msg); \ + item->SetTarget(Window()); \ +\ + if (!(chat->DisallowedFlags() &flag)) { \ + if (chat->GetFlags() & flag) \ + item->SetMarked(true); \ + menu->AddItem(item); \ + } \ +} + + +void +ConversationListView::_AddDefaultItems(BPopUpMenu* menu, + Conversation* chat) +{ + if (chat == NULL || menu == NULL) + return; + BString id = chat->GetId(); + ProtocolLooper* looper = chat->GetProtocolLooper(); + int64 instance = looper->GetInstance(); + + BMessage* infoMsg = new BMessage(APP_ROOM_INFO); + infoMsg->AddString("chat_id", id); + infoMsg->AddInt64("instance", instance); + BMenuItem* joinItem = new BMenuItem(B_TRANSLATE("Room info…"), infoMsg); + joinItem->SetTarget(Window()); + menu->AddItem(joinItem); + + menu->AddSeparatorItem(); + + BMessage* msg; + BMenuItem* item; + add_flag_item(B_TRANSLATE("Auto-join room"), ROOM_AUTOJOIN); + add_flag_item(B_TRANSLATE("Log messages"), ROOM_LOG_LOCALLY); + add_flag_item(B_TRANSLATE("Notify on every message"), ROOM_NOTIFY_ALL); + add_flag_item(B_TRANSLATE("Notify on direct-messages"), ROOM_NOTIFY_DM); + + menu->AddSeparatorItem(); + + BMessage* leaveMsg = new BMessage(IM_MESSAGE); + leaveMsg->AddInt32("im_what", IM_LEAVE_ROOM); + leaveMsg->AddString("chat_id", id); + leaveMsg->AddInt64("instance", instance); + BMenuItem* leave = new BMenuItem(B_TRANSLATE("Leave room"), leaveMsg); + leave->SetTarget(looper); + menu->AddItem(leave); +} + + BPopUpMenu* ConversationListView::_BlankPopUp() { diff --git a/application/views/ConversationListView.h b/application/views/ConversationListView.h index 9ee8c25..a1eda00 100644 --- a/application/views/ConversationListView.h +++ b/application/views/ConversationListView.h @@ -31,6 +31,7 @@ public: private: BPopUpMenu* _ConversationPopUp(); + void _AddDefaultItems(BPopUpMenu* menu, Conversation* chat); BPopUpMenu* _BlankPopUp(); ConversationAccountItem* diff --git a/data/misc/Templates.rdef b/data/misc/Templates.rdef index ff69dac..3a5c4bf 100644 --- a/data/misc/Templates.rdef +++ b/data/misc/Templates.rdef @@ -115,23 +115,6 @@ resource(1106) message }; -// Room pop-up menu items -resource(1120) message -{ - "class" = "BMenuItem", - "_label" = "Room info…", - "_msg" = message('CYrw'), - bool "x_to_protocol" = false -}; -resource(1121) message -{ - "class" = "BMenuItem", - "_label" = "Leave chat", - "_msg" = message('IMme') { int32 "im_what" = 156 }, - bool "x_to_protocol" = true -}; - - // Chat commands resource(1140) message {