Toggling of room flags through right-click menu

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!
This commit is contained in:
Jaidyn Ann 2021-08-19 00:59:03 -05:00
parent a9eeaa51fe
commit d8d89d245e
10 changed files with 121 additions and 65 deletions

View File

@ -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';

View File

@ -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" */

View File

@ -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)
{

View File

@ -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);

View File

@ -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

View File

@ -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<BMessage>
Server::ChatPopUpItems()
{
return fChatItems;
}
BObjectList<BMessage>
Server::UserPopUpItems()
{

View File

@ -67,7 +67,6 @@ public:
CommandMap Commands(int64 instance);
ChatCommand* CommandById(BString id, int64 instance);
BObjectList<BMessage> ChatPopUpItems();
BObjectList<BMessage> UserPopUpItems();
private:
@ -94,7 +93,6 @@ private:
bool fStarted;
CommandMap fCommands;
BObjectList<BMessage> fChatItems;
BObjectList<BMessage> fUserItems;
};

View File

@ -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<BMessage> items = server->ChatPopUpItems();
BObjectList<BMessage> protoItems = looper->Protocol()->ChatPopUpItems();
items.AddList(&protoItems);
_AddDefaultItems(menu, chat);
BObjectList<BMessage> 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()
{

View File

@ -31,6 +31,7 @@ public:
private:
BPopUpMenu* _ConversationPopUp();
void _AddDefaultItems(BPopUpMenu* menu, Conversation* chat);
BPopUpMenu* _BlankPopUp();
ConversationAccountItem*

View File

@ -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
{