Basis for custom userlist pop-up menu items

This commit is contained in:
Jaidyn Ann 2021-06-15 21:05:21 -05:00
parent 83e98bd5a8
commit 66b8150eeb
8 changed files with 261 additions and 174 deletions

View File

@ -50,4 +50,7 @@ const uint32 CAYA_DISABLE_ACCOUNT = 'CYda';
//! Request a "help" message
const uint32 CAYA_REQUEST_HELP = 'CYhm';
//! Display a "user info" window
const uint32 CAYA_USER_INFO = 'CYuw';
#endif // _CAYA_MESSAGES_H

View File

@ -0,0 +1,149 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "DefaultItems.h"
#include <InterfaceDefs.h>
#include "CayaMessages.h"
#include "CayaProtocolMessages.h"
#include "Role.h"
CommandMap
DefaultCommands()
{
List<int32> roomUser;
roomUser.AddItem(CMD_ROOM_PARTICIPANT);
List<int32> kickBody;
kickBody.AddItem(CMD_ROOM_PARTICIPANT);
kickBody.AddItem(CMD_BODY_STRING);
List<int32> knownUser;
knownUser.AddItem(CMD_KNOWN_USER);
List<int32> anyUser;
anyUser.AddItem(CMD_ANY_USER);
CommandMap commands;
BMessage kickMsg(IM_MESSAGE);
kickMsg.AddInt32("im_what", IM_ROOM_KICK_PARTICIPANT);
ChatCommand* kick = new ChatCommand("kick", kickMsg, true, kickBody);
kick->SetDesc("Force a user to temporarily leave the room, assuming your "
"power level's high enough.");
commands.AddItem("kick", kick);
BMessage banMsg(IM_MESSAGE);
banMsg.AddInt32("im_what", IM_ROOM_BAN_PARTICIPANT);
ChatCommand* ban = new ChatCommand("ban", banMsg, true, kickBody);
ban->SetDesc("Kick a user out of the room and slam the door behind them― "
"locking it while you're at it.");
commands.AddItem("ban", ban);
BMessage unbanMsg(IM_MESSAGE);
unbanMsg.AddInt32("im_what", IM_ROOM_UNBAN_PARTICIPANT);
ChatCommand* unban = new ChatCommand("unban", unbanMsg, true, anyUser);
unban->SetDesc("Undo a previous ban, allowing the user to rejoin (if they "
"still want to).");
commands.AddItem("unban", unban);
BMessage muteMsg(IM_MESSAGE);
muteMsg.AddInt32("im_what", IM_ROOM_MUTE_PARTICIPANT);
ChatCommand* mute = new ChatCommand("mute", muteMsg, true, roomUser);
mute->SetDesc("Disallow a user from sending visible messages.");
commands.AddItem("mute", mute);
BMessage unmuteMsg(IM_MESSAGE);
unmuteMsg.AddInt32("im_what", IM_ROOM_UNMUTE_PARTICIPANT);
ChatCommand* unmute = new ChatCommand("unmute", unmuteMsg, true, roomUser);
unmute->SetDesc("Restore a user's ability to send messages.");
commands.AddItem("unmute", unmute);
BMessage deafenMsg(IM_MESSAGE);
deafenMsg.AddInt32("im_what", IM_ROOM_DEAFEN_PARTICIPANT);
ChatCommand* deafen = new ChatCommand("deafen", deafenMsg, true, roomUser);
deafen->SetDesc("Disallow a user from reading messages sent in the room.");
commands.AddItem("deafen", deafen);
BMessage undeafenMsg(IM_MESSAGE);
undeafenMsg.AddInt32("im_what", IM_ROOM_UNDEAFEN_PARTICIPANT);
ChatCommand* undeafen = new ChatCommand("undeafen", undeafenMsg, true, roomUser);
undeafen->SetDesc("Restore a user's ability to receive messages.");
commands.AddItem("undeafen", undeafen);
BMessage inviteMsg(IM_MESSAGE);
inviteMsg.AddInt32("im_what", IM_ROOM_SEND_INVITE);
ChatCommand* invite = new ChatCommand("invite", inviteMsg, true, knownUser);
invite->SetDesc("Invite a user to the current room.");
commands.AddItem("invite", invite);
BMessage helpMsg(CAYA_REQUEST_HELP);
ChatCommand* help = new ChatCommand("help", helpMsg, false, List<int>());
help->SetDesc("List all current commands, or get help for certain command.");
commands.AddItem("help", help);
return commands;
}
BObjectList<BMessage>
DefaultUserPopUpItems()
{
BObjectList<BMessage> items;
BMessage* infoMsg = new BMessage(CAYA_USER_INFO);
items.AddItem(_UserMenuItem("User info" B_UTF8_ELLIPSIS, infoMsg, 0, 0, 0,
false, false));
BMessage* kickMsg = new BMessage(IM_MESSAGE);
kickMsg->AddInt32("im_what", IM_ROOM_KICK_PARTICIPANT);
items.AddItem(_UserMenuItem("Kick user", kickMsg, PERM_KICK, 0, 0, false,
true));
BMessage* banMsg = new BMessage(IM_MESSAGE);
banMsg->AddInt32("im_what", IM_ROOM_BAN_PARTICIPANT);
items.AddItem(_UserMenuItem("Ban user", banMsg, PERM_BAN, 0, 0, false, true));
BMessage* muteMsg = new BMessage(IM_MESSAGE);
muteMsg->AddInt32("im_what", IM_ROOM_MUTE_PARTICIPANT);
items.AddItem(_UserMenuItem("Mute user", muteMsg, PERM_MUTE, PERM_WRITE, 0,
false, true));
BMessage* unmuteMsg = new BMessage(IM_MESSAGE);
unmuteMsg->AddInt32("im_what", IM_ROOM_UNMUTE_PARTICIPANT);
items.AddItem(_UserMenuItem("Unmute user", unmuteMsg, PERM_MUTE, 0,
PERM_WRITE, false, true));
BMessage* deafenMsg = new BMessage(IM_MESSAGE);
deafenMsg->AddInt32("im_what", IM_ROOM_DEAFEN_PARTICIPANT);
items.AddItem(_UserMenuItem("Deafen user", deafenMsg, PERM_DEAFEN, PERM_READ,
0, false, true));
BMessage* undeafenMsg = new BMessage(IM_MESSAGE);
undeafenMsg->AddInt32("im_what", IM_ROOM_UNDEAFEN_PARTICIPANT);
items.AddItem(_UserMenuItem("Undeafen user", undeafenMsg, PERM_DEAFEN, 0,
PERM_READ, false, true));
return items;
}
BMessage*
_UserMenuItem(const char* label, BMessage* msg, int32 user_perms,
int32 target_perms, int32 target_lacks, bool ignorePriority,
bool toProtocol)
{
BMessage* item = new BMessage();
item->AddString("class", "BMenuItem");
item->AddString("_label", label);
item->AddMessage("_msg", msg);
item->AddInt32("x_perms", user_perms);
item->AddInt32("x_target_perms", target_perms);
item->AddInt32("x_target_antiperms", target_lacks);
item->AddBool("x_priority", ignorePriority);
item->AddBool("x_to_protocol", toProtocol);
return item;
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef DEFAULTITEMS_H
#define DEFAULTITEMS_H
#include "ChatCommand.h"
#include <ObjectList.h>
CommandMap DefaultCommands();
BObjectList<BMessage> DefaultUserPopUpItems();
BMessage* _UserMenuItem(const char* label, BMessage* msg,
int32 user_perms, int32 target_perms,
int32 target_lacks, bool ignorePriority,
bool toProtocol);
#endif // DEFAULTITEMS_H

View File

@ -39,6 +39,7 @@ SRCS = \
application/ChatCommand.cpp \
application/Contact.cpp \
application/Conversation.cpp \
application/DefaultItems.cpp \
application/EditingFilter.cpp \
application/ImageCache.cpp \
application/Main.cpp \

View File

@ -1,16 +1,20 @@
/*
* Copyright 2009-2011, Andrea Anzani. All rights reserved.
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Andrea Anzani, andrea.anzani@gmail.com
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
* Jaidyn Levesque, jadedctrl@teknik.io
*
* Contributors:
* Dario Casalinuovo
*/
#include "Server.h"
#include <Application.h>
#include <Debug.h>
#include <Entry.h>
@ -26,20 +30,22 @@
#include "CayaPreferences.h"
#include "CayaProtocolMessages.h"
#include "CayaUtils.h"
#include "DefaultItems.h"
#include "ImageCache.h"
#include "InviteDialogue.h"
#include "ProtocolLooper.h"
#include "ProtocolManager.h"
#include "RoomFlags.h"
#include "RosterItem.h"
#include "Server.h"
#include "UserInfoWindow.h"
Server::Server()
:
BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE)
BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
fUserItems(DefaultUserPopUpItems()),
fCommands(DefaultCommands())
{
_InitDefaultCommands();
}
@ -113,6 +119,16 @@ Server::Filter(BMessage* message, BHandler **target)
break;
}
case CAYA_USER_INFO:
{
User* user = _EnsureUser(message);
if (user != NULL) {
UserInfoWindow* win = new UserInfoWindow(user);
win->Show();
}
break;
}
case CAYA_REQUEST_HELP:
{
BString body;
@ -749,19 +765,6 @@ Server::AddConversation(Conversation* chat, int64 instance)
}
CommandMap
Server::Commands()
{
CommandMap commands = fCommands;
for (int i = 0; i < fAccounts.CountItems(); i++) {
ProtocolLooper* fruitLoop = fLoopers.ValueFor(fAccounts.ValueAt(i));
if (fruitLoop == NULL) continue;
commands.AddList(fruitLoop->Commands());
}
return fCommands;
}
ChatCommand*
Server::CommandById(BString id, int64 instance)
{
@ -775,6 +778,20 @@ Server::CommandById(BString id, int64 instance)
}
BObjectList<BMessage>
Server::ConversationPopUpItems()
{
return fChatItems;
}
BObjectList<BMessage>
Server::UserPopUpItems()
{
return fUserItems;
}
ProtocolLooper*
Server::_LooperFromMessage(BMessage* message)
{
@ -890,74 +907,4 @@ Server::_GetRole(BMessage* msg)
return new Role(title, perms, priority);
}
void
Server::_InitDefaultCommands()
{
List<int32> roomUser;
roomUser.AddItem(CMD_ROOM_PARTICIPANT);
List<int32> kickBody;
kickBody.AddItem(CMD_ROOM_PARTICIPANT);
kickBody.AddItem(CMD_BODY_STRING);
List<int32> knownUser;
knownUser.AddItem(CMD_KNOWN_USER);
List<int32> anyUser;
anyUser.AddItem(CMD_ANY_USER);
BMessage kickMsg(IM_MESSAGE);
kickMsg.AddInt32("im_what", IM_ROOM_KICK_PARTICIPANT);
ChatCommand* kick = new ChatCommand("kick", kickMsg, true, kickBody);
kick->SetDesc("Force a user to temporarily leave the room, assuming your "
"power level's high enough.");
fCommands.AddItem("kick", kick);
BMessage banMsg(IM_MESSAGE);
banMsg.AddInt32("im_what", IM_ROOM_BAN_PARTICIPANT);
ChatCommand* ban = new ChatCommand("ban", banMsg, true, kickBody);
ban->SetDesc("Kick a user out of the room and slam the door behind them― "
"locking it while you're at it.");
fCommands.AddItem("ban", ban);
BMessage unbanMsg(IM_MESSAGE);
unbanMsg.AddInt32("im_what", IM_ROOM_UNBAN_PARTICIPANT);
ChatCommand* unban = new ChatCommand("unban", unbanMsg, true, anyUser);
unban->SetDesc("Undo a previous ban, allowing the user to rejoin (if they "
"still want to).");
fCommands.AddItem("unban", unban);
BMessage muteMsg(IM_MESSAGE);
muteMsg.AddInt32("im_what", IM_ROOM_MUTE_PARTICIPANT);
ChatCommand* mute = new ChatCommand("mute", muteMsg, true, roomUser);
mute->SetDesc("Disallow a user from sending visible messages.");
fCommands.AddItem("mute", mute);
BMessage unmuteMsg(IM_MESSAGE);
unmuteMsg.AddInt32("im_what", IM_ROOM_UNMUTE_PARTICIPANT);
ChatCommand* unmute = new ChatCommand("unmute", unmuteMsg, true, roomUser);
unmute->SetDesc("Restore a user's ability to send messages.");
fCommands.AddItem("unmute", unmute);
BMessage deafenMsg(IM_MESSAGE);
deafenMsg.AddInt32("im_what", IM_ROOM_DEAFEN_PARTICIPANT);
ChatCommand* deafen = new ChatCommand("deafen", deafenMsg, true, roomUser);
deafen->SetDesc("Disallow a user from reading messages sent in the room.");
fCommands.AddItem("deafen", deafen);
BMessage undeafenMsg(IM_MESSAGE);
undeafenMsg.AddInt32("im_what", IM_ROOM_UNDEAFEN_PARTICIPANT);
ChatCommand* undeafen = new ChatCommand("undeafen", undeafenMsg, true, roomUser);
undeafen->SetDesc("Restore a user's ability to receive messages.");
fCommands.AddItem("undeafen", undeafen);
BMessage inviteMsg(IM_MESSAGE);
inviteMsg.AddInt32("im_what", IM_ROOM_SEND_INVITE);
ChatCommand* invite = new ChatCommand("invite", inviteMsg, true, knownUser);
invite->SetDesc("Invite a user to the current room.");
fCommands.AddItem("invite", invite);
BMessage helpMsg(CAYA_REQUEST_HELP);
ChatCommand* help = new ChatCommand("help", helpMsg, false, List<int>());
help->SetDesc("List all current commands, or get help for certain command.");
fCommands.AddItem("help", help);
}

View File

@ -59,9 +59,11 @@ public:
Conversation* ConversationById(BString id, int64 instance);
void AddConversation(Conversation* chat, int64 instance);
CommandMap Commands();
ChatCommand* CommandById(BString id, int64 instance);
BObjectList<BMessage> ConversationPopUpItems();
BObjectList<BMessage> UserPopUpItems();
private:
ProtocolLooper* _LooperFromMessage(BMessage* message);
@ -72,14 +74,18 @@ private:
Role* _GetRole(BMessage* msg);
void _InitDefaultCommands();
void _ReplicantStatusNotify(CayaStatus status);
ProtocolLoopers fLoopers;
AccountInstances
fAccounts;
CommandMap fCommands;
BString fMySelf;
CommandMap fCommands;
BObjectList<BMessage>
fChatItems;
BObjectList<BMessage>
fUserItems;
};

View File

@ -12,8 +12,11 @@
#include "CayaMessages.h"
#include "CayaProtocolMessages.h"
#include "Conversation.h"
#include "MainWindow.h"
#include "ProtocolLooper.h"
#include "Role.h"
#include "Server.h"
#include "TheApp.h"
#include "User.h"
#include "UserInfoWindow.h"
#include "UserItem.h"
@ -27,44 +30,6 @@ UserListView::UserListView(const char* name)
}
void
UserListView::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case kUserInfo:
{
UserItem* item = (UserItem*)ItemAt(CurrentSelection());
if (item == NULL)
return;
UserInfoWindow* win = new UserInfoWindow(item->GetUser());
win->Show();
break;
}
case kKickUser:
_ModerationAction(IM_ROOM_KICK_PARTICIPANT);
break;
case kBanUser:
_ModerationAction(IM_ROOM_BAN_PARTICIPANT);
break;
case kMuteUser:
_ModerationAction(IM_ROOM_MUTE_PARTICIPANT);
break;
case kUnmuteUser:
_ModerationAction(IM_ROOM_UNMUTE_PARTICIPANT);
break;
case kDeafenUser:
_ModerationAction(IM_ROOM_DEAFEN_PARTICIPANT);
break;
case kUndeafenUser:
_ModerationAction(IM_ROOM_UNDEAFEN_PARTICIPANT);
break;
default:
BListView::MessageReceived(msg);
}
}
void
UserListView::MouseDown(BPoint where)
{
@ -87,47 +52,24 @@ BPopUpMenu*
UserListView::_UserPopUp()
{
BPopUpMenu* menu = new BPopUpMenu("userPopUp");
menu->AddItem(new BMenuItem("User info" B_UTF8_ELLIPSIS,
new BMessage(kUserInfo)));
menu->SetTargetForItems(this);
// Now for the moderation items
Role* role = fChat->GetRole(fChat->GetOwnId());
if (role == NULL) return menu;
int32 perms = role->fPerms;
UserItem* item = (UserItem*)ItemAt(CurrentSelection());
User* selected_user;
if (item == NULL || (selected_user = item->GetUser()) == NULL)
return menu;
return _BlankPopUp();
Role* own_role = fChat->GetRole(fChat->GetOwnId());
if (own_role == NULL) return _BlankPopUp();
Role* selected_role = fChat->GetRole(selected_user->GetId());
if (selected_role == NULL) return menu;
int32 selected_priority = selected_role->fPriority;
int32 selected_perms = selected_role->fPerms;
if (selected_priority > role->fPriority)
return menu;
if (selected_role == NULL) return _BlankPopUp();
if ((perms & PERM_DEAFEN) || (perms & PERM_MUTE) || (perms & PERM_KICK)
|| (perms & PERM_BAN))
menu->AddSeparatorItem();
Server* server = ((TheApp*)be_app)->GetMainWindow()->GetServer();
BObjectList<BMessage> items = server->UserPopUpItems();
if ((perms & PERM_DEAFEN) && (selected_perms & PERM_READ))
menu->AddItem(new BMenuItem("Deafen user", new BMessage(kDeafenUser)));
if ((perms & PERM_DEAFEN) && !(selected_perms & PERM_READ))
menu->AddItem(new BMenuItem("Undeafen user", new BMessage(kUndeafenUser)));
if ((perms & PERM_MUTE) && (selected_perms & PERM_WRITE))
menu->AddItem(new BMenuItem("Mute user", new BMessage(kMuteUser)));
if ((perms & PERM_MUTE) && !(selected_perms & PERM_WRITE))
menu->AddItem(new BMenuItem("Unmute user", new BMessage(kUnmuteUser)));
if (perms & PERM_KICK)
menu->AddItem(new BMenuItem("Kick user", new BMessage(kKickUser)));
if (perms & PERM_BAN)
menu->AddItem(new BMenuItem("Ban user", new BMessage(kBanUser)));
menu->SetTargetForItems(this);
for (int i = 0; i < items.CountItems(); i++) {
BMessage* itemMsg = items.ItemAt(i);
_ProcessItem(itemMsg, menu, own_role, selected_role, selected_user->GetId());
}
return menu;
}
@ -150,19 +92,35 @@ UserListView::_BlankPopUp()
void
UserListView::_ModerationAction(int32 im_what)
UserListView::_ProcessItem(BMessage* itemMsg, BPopUpMenu* menu, Role* user,
Role* target, BString target_id)
{
Role* role = fChat->GetRole(fChat->GetOwnId());
int32 perms = role->fPerms;
UserItem* item = (UserItem*)ItemAt(CurrentSelection());
if (item == NULL)
return;
BMessage* msg = new BMessage(*itemMsg);
bool priority = msg->GetBool("x_priority", false);
int32 perms = msg->GetInt32("x_perms", 0);
int32 target_perms = msg->GetInt32("x_target_perms", 0);
int32 target_antiperms = msg->GetInt32("x_target_antiperms", 0);
BMessage modMsg(IM_MESSAGE);
modMsg.AddInt32("im_what", im_what);
modMsg.AddString("user_id", item->GetUser()->GetId());
modMsg.AddString("chat_id", fChat->GetId());
fChat->GetProtocolLooper()->PostMessage(&modMsg);
BMessage toSend;
msg->FindMessage("_msg", &toSend);
toSend.AddString("user_id", target_id);
toSend.AddString("chat_id", fChat->GetId());
toSend.AddInt64("instance", fChat->GetProtocolLooper()->GetInstance());
msg->ReplaceMessage("_msg", &toSend);
if ((perms == 0 || (user->fPerms & perms))
&& (target_perms == 0 || (target->fPerms & target_perms))
&& (target_antiperms == 0 || (!(target->fPerms & target_antiperms)))
&& ((priority == false) || (user->fPriority > target->fPriority)))
{
BMenuItem* item = new BMenuItem(msg);
if (msg->GetBool("x_to_protocol", true) == true)
item->SetTarget(fChat->GetProtocolLooper());
else
item->SetTarget(Window());
menu->AddItem(item);
}
}

View File

@ -7,6 +7,8 @@
#include <ListView.h>
#include "Role.h"
class BPopUpMenu;
class Conversation;
@ -27,8 +29,6 @@ class UserListView : public BListView {
public:
UserListView(const char* name);
void MessageReceived(BMessage* msg);
void MouseDown(BPoint where);
void SetConversation(Conversation* chat) { fChat = chat; }
@ -38,6 +38,8 @@ private:
BPopUpMenu* _BlankPopUp();
void _ModerationAction(int32 im_what);
void _ProcessItem(BMessage* itemMsg, BPopUpMenu* menu, Role* user,
Role* target, BString target_id);
Conversation* fChat;
};