mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	citra_qt: Add a moderation dialog
The dialog currently supports accessing the ban list and removing entries from it.
This commit is contained in:
		
							parent
							
								
									7acd2664dd
								
							
						
					
					
						commit
						6359b6094c
					
				
					 9 changed files with 273 additions and 0 deletions
				
			
		|  | @ -99,6 +99,8 @@ add_executable(citra-qt | ||||||
|     multiplayer/lobby.cpp |     multiplayer/lobby.cpp | ||||||
|     multiplayer/message.h |     multiplayer/message.h | ||||||
|     multiplayer/message.cpp |     multiplayer/message.cpp | ||||||
|  |     multiplayer/moderation_dialog.cpp | ||||||
|  |     multiplayer/moderation_dialog.h | ||||||
|     multiplayer/state.cpp |     multiplayer/state.cpp | ||||||
|     multiplayer/state.h |     multiplayer/state.h | ||||||
|     multiplayer/validation.h |     multiplayer/validation.h | ||||||
|  | @ -135,6 +137,7 @@ set(UIS | ||||||
|     multiplayer/chat_room.ui |     multiplayer/chat_room.ui | ||||||
|     multiplayer/client_room.ui |     multiplayer/client_room.ui | ||||||
|     multiplayer/host_room.ui |     multiplayer/host_room.ui | ||||||
|  |     multiplayer/moderation_dialog.ui | ||||||
|     aboutdialog.ui |     aboutdialog.ui | ||||||
|     cheats.ui |     cheats.ui | ||||||
|     hotkeys.ui |     hotkeys.ui | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ | ||||||
| #include "citra_qt/game_list_p.h" | #include "citra_qt/game_list_p.h" | ||||||
| #include "citra_qt/multiplayer/client_room.h" | #include "citra_qt/multiplayer/client_room.h" | ||||||
| #include "citra_qt/multiplayer/message.h" | #include "citra_qt/multiplayer/message.h" | ||||||
|  | #include "citra_qt/multiplayer/moderation_dialog.h" | ||||||
| #include "citra_qt/multiplayer/state.h" | #include "citra_qt/multiplayer/state.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "core/announce_multiplayer_session.h" | #include "core/announce_multiplayer_session.h" | ||||||
|  | @ -42,11 +43,23 @@ ClientRoomWindow::ClientRoomWindow(QWidget* parent) | ||||||
|     connect(ui->disconnect, &QPushButton::pressed, [this] { Disconnect(); }); |     connect(ui->disconnect, &QPushButton::pressed, [this] { Disconnect(); }); | ||||||
|     ui->disconnect->setDefault(false); |     ui->disconnect->setDefault(false); | ||||||
|     ui->disconnect->setAutoDefault(false); |     ui->disconnect->setAutoDefault(false); | ||||||
|  |     connect(ui->moderation, &QPushButton::clicked, [this] { | ||||||
|  |         ModerationDialog dialog(this); | ||||||
|  |         dialog.exec(); | ||||||
|  |     }); | ||||||
|  |     ui->moderation->setDefault(false); | ||||||
|  |     ui->moderation->setAutoDefault(false); | ||||||
|     UpdateView(); |     UpdateView(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ClientRoomWindow::~ClientRoomWindow() = default; | ClientRoomWindow::~ClientRoomWindow() = default; | ||||||
| 
 | 
 | ||||||
|  | void ClientRoomWindow::SetModPerms(bool is_mod) { | ||||||
|  |     ui->moderation->setVisible(is_mod); | ||||||
|  |     ui->moderation->setDefault(false); | ||||||
|  |     ui->moderation->setAutoDefault(false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ClientRoomWindow::RetranslateUi() { | void ClientRoomWindow::RetranslateUi() { | ||||||
|     ui->retranslateUi(this); |     ui->retranslateUi(this); | ||||||
|     ui->chat->RetranslateUi(); |     ui->chat->RetranslateUi(); | ||||||
|  |  | ||||||
|  | @ -18,6 +18,7 @@ public: | ||||||
|     ~ClientRoomWindow(); |     ~ClientRoomWindow(); | ||||||
| 
 | 
 | ||||||
|     void RetranslateUi(); |     void RetranslateUi(); | ||||||
|  |     void SetModPerms(bool is_mod); | ||||||
| 
 | 
 | ||||||
| public slots: | public slots: | ||||||
|     void OnRoomUpdate(const Network::RoomInformation&); |     void OnRoomUpdate(const Network::RoomInformation&); | ||||||
|  |  | ||||||
|  | @ -41,6 +41,16 @@ | ||||||
|          </property> |          </property> | ||||||
|         </spacer> |         </spacer> | ||||||
|        </item> |        </item> | ||||||
|  |        <item> | ||||||
|  |         <widget class="QPushButton" name="moderation"> | ||||||
|  |          <property name="text"> | ||||||
|  |           <string>Moderation...</string> | ||||||
|  |          </property> | ||||||
|  |          <property name="visible"> | ||||||
|  |           <bool>false</bool> | ||||||
|  |          </property> | ||||||
|  |         </widget> | ||||||
|  |        </item> | ||||||
|        <item> |        <item> | ||||||
|         <widget class="QPushButton" name="disconnect"> |         <widget class="QPushButton" name="disconnect"> | ||||||
|          <property name="text"> |          <property name="text"> | ||||||
|  |  | ||||||
							
								
								
									
										113
									
								
								src/citra_qt/multiplayer/moderation_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								src/citra_qt/multiplayer/moderation_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,113 @@ | ||||||
|  | // Copyright 2018 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include <QStandardItem> | ||||||
|  | #include <QStandardItemModel> | ||||||
|  | #include "citra_qt/multiplayer/moderation_dialog.h" | ||||||
|  | #include "network/network.h" | ||||||
|  | #include "network/room_member.h" | ||||||
|  | #include "ui_moderation_dialog.h" | ||||||
|  | 
 | ||||||
|  | namespace Column { | ||||||
|  | enum { | ||||||
|  |     SUBJECT, | ||||||
|  |     TYPE, | ||||||
|  |     COUNT, | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ModerationDialog::ModerationDialog(QWidget* parent) | ||||||
|  |     : QDialog(parent), ui(std::make_unique<Ui::ModerationDialog>()) { | ||||||
|  |     ui->setupUi(this); | ||||||
|  | 
 | ||||||
|  |     qRegisterMetaType<Network::Room::BanList>(); | ||||||
|  | 
 | ||||||
|  |     if (auto member = Network::GetRoomMember().lock()) { | ||||||
|  |         callback_handle_status_message = member->BindOnStatusMessageReceived( | ||||||
|  |             [this](const Network::StatusMessageEntry& status_message) { | ||||||
|  |                 emit StatusMessageReceived(status_message); | ||||||
|  |             }); | ||||||
|  |         connect(this, &ModerationDialog::StatusMessageReceived, this, | ||||||
|  |                 &ModerationDialog::OnStatusMessageReceived); | ||||||
|  |         callback_handle_ban_list = member->BindOnBanListReceived( | ||||||
|  |             [this](const Network::Room::BanList& ban_list) { emit BanListReceived(ban_list); }); | ||||||
|  |         connect(this, &ModerationDialog::BanListReceived, this, &ModerationDialog::PopulateBanList); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Initialize the UI
 | ||||||
|  |     model = new QStandardItemModel(ui->ban_list_view); | ||||||
|  |     model->insertColumns(0, Column::COUNT); | ||||||
|  |     model->setHeaderData(Column::SUBJECT, Qt::Horizontal, tr("Subject")); | ||||||
|  |     model->setHeaderData(Column::TYPE, Qt::Horizontal, tr("Type")); | ||||||
|  | 
 | ||||||
|  |     ui->ban_list_view->setModel(model); | ||||||
|  | 
 | ||||||
|  |     // Load the ban list in background
 | ||||||
|  |     LoadBanList(); | ||||||
|  | 
 | ||||||
|  |     connect(ui->refresh, &QPushButton::clicked, this, [this] { LoadBanList(); }); | ||||||
|  |     connect(ui->unban, &QPushButton::clicked, this, [this] { | ||||||
|  |         auto index = ui->ban_list_view->currentIndex(); | ||||||
|  |         SendUnbanRequest(model->item(index.row(), 0)->text()); | ||||||
|  |     }); | ||||||
|  |     connect(ui->ban_list_view, &QTreeView::clicked, [this] { ui->unban->setEnabled(true); }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ModerationDialog::~ModerationDialog() { | ||||||
|  |     if (callback_handle_status_message) { | ||||||
|  |         if (auto room = Network::GetRoomMember().lock()) { | ||||||
|  |             room->Unbind(callback_handle_status_message); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (callback_handle_ban_list) { | ||||||
|  |         if (auto room = Network::GetRoomMember().lock()) { | ||||||
|  |             room->Unbind(callback_handle_ban_list); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ModerationDialog::LoadBanList() { | ||||||
|  |     if (auto room = Network::GetRoomMember().lock()) { | ||||||
|  |         ui->refresh->setEnabled(false); | ||||||
|  |         ui->refresh->setText(tr("Refreshing")); | ||||||
|  |         ui->unban->setEnabled(false); | ||||||
|  |         room->RequestBanList(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ModerationDialog::PopulateBanList(const Network::Room::BanList& ban_list) { | ||||||
|  |     model->removeRows(0, model->rowCount()); | ||||||
|  |     for (const auto& username : ban_list.first) { | ||||||
|  |         QStandardItem* subject_item = new QStandardItem(QString::fromStdString(username)); | ||||||
|  |         QStandardItem* type_item = new QStandardItem(tr("Forum Username")); | ||||||
|  |         model->invisibleRootItem()->appendRow({subject_item, type_item}); | ||||||
|  |     } | ||||||
|  |     for (const auto& ip : ban_list.second) { | ||||||
|  |         QStandardItem* subject_item = new QStandardItem(QString::fromStdString(ip)); | ||||||
|  |         QStandardItem* type_item = new QStandardItem(tr("IP Address")); | ||||||
|  |         model->invisibleRootItem()->appendRow({subject_item, type_item}); | ||||||
|  |     } | ||||||
|  |     for (int i = 0; i < Column::COUNT - 1; ++i) { | ||||||
|  |         ui->ban_list_view->resizeColumnToContents(i); | ||||||
|  |     } | ||||||
|  |     ui->refresh->setEnabled(true); | ||||||
|  |     ui->refresh->setText(tr("Refresh")); | ||||||
|  |     ui->unban->setEnabled(false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ModerationDialog::SendUnbanRequest(const QString& subject) { | ||||||
|  |     if (auto room = Network::GetRoomMember().lock()) { | ||||||
|  |         room->SendModerationRequest(Network::IdModUnban, subject.toStdString()); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ModerationDialog::OnStatusMessageReceived(const Network::StatusMessageEntry& status_message) { | ||||||
|  |     if (status_message.type != Network::IdMemberBanned && | ||||||
|  |         status_message.type != Network::IdAddressUnbanned) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     // Update the ban list for ban/unban
 | ||||||
|  |     LoadBanList(); | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								src/citra_qt/multiplayer/moderation_dialog.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/citra_qt/multiplayer/moderation_dialog.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | ||||||
|  | // Copyright 2018 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | #include <optional> | ||||||
|  | #include <QDialog> | ||||||
|  | #include "network/room.h" | ||||||
|  | #include "network/room_member.h" | ||||||
|  | 
 | ||||||
|  | namespace Ui { | ||||||
|  | class ModerationDialog; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class QStandardItemModel; | ||||||
|  | 
 | ||||||
|  | class ModerationDialog : public QDialog { | ||||||
|  |     Q_OBJECT | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     explicit ModerationDialog(QWidget* parent = nullptr); | ||||||
|  |     ~ModerationDialog(); | ||||||
|  | 
 | ||||||
|  | signals: | ||||||
|  |     void StatusMessageReceived(const Network::StatusMessageEntry&); | ||||||
|  |     void BanListReceived(const Network::Room::BanList&); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     void LoadBanList(); | ||||||
|  |     void PopulateBanList(const Network::Room::BanList& ban_list); | ||||||
|  |     void SendUnbanRequest(const QString& subject); | ||||||
|  |     void OnStatusMessageReceived(const Network::StatusMessageEntry& status_message); | ||||||
|  | 
 | ||||||
|  |     std::unique_ptr<Ui::ModerationDialog> ui; | ||||||
|  |     QStandardItemModel* model; | ||||||
|  |     Network::RoomMember::CallbackHandle<Network::StatusMessageEntry> callback_handle_status_message; | ||||||
|  |     Network::RoomMember::CallbackHandle<Network::Room::BanList> callback_handle_ban_list; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | Q_DECLARE_METATYPE(Network::Room::BanList); | ||||||
							
								
								
									
										84
									
								
								src/citra_qt/multiplayer/moderation_dialog.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/citra_qt/multiplayer/moderation_dialog.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,84 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <ui version="4.0"> | ||||||
|  |  <class>ModerationDialog</class> | ||||||
|  |  <widget class="QDialog" name="ModerationDialog"> | ||||||
|  |   <property name="windowTitle"> | ||||||
|  |    <string>Moderation</string> | ||||||
|  |   </property> | ||||||
|  |   <property name="geometry"> | ||||||
|  |    <rect> | ||||||
|  |     <x>0</x> | ||||||
|  |     <y>0</y> | ||||||
|  |     <width>500</width> | ||||||
|  |     <height>300</height> | ||||||
|  |    </rect> | ||||||
|  |   </property> | ||||||
|  |   <layout class="QVBoxLayout"> | ||||||
|  |    <item> | ||||||
|  |     <widget class="QGroupBox" name="ban_list_group_box"> | ||||||
|  |      <property name="title"> | ||||||
|  |       <string>Ban List</string> | ||||||
|  |      </property> | ||||||
|  |      <layout class="QVBoxLayout"> | ||||||
|  |       <item> | ||||||
|  |        <layout class="QHBoxLayout"> | ||||||
|  |         <item> | ||||||
|  |          <spacer name="horizontalSpacer"> | ||||||
|  |           <property name="orientation"> | ||||||
|  |            <enum>Qt::Horizontal</enum> | ||||||
|  |           </property> | ||||||
|  |           <property name="sizeHint" stdset="0"> | ||||||
|  |            <size> | ||||||
|  |             <width>40</width> | ||||||
|  |             <height>20</height> | ||||||
|  |            </size> | ||||||
|  |           </property> | ||||||
|  |          </spacer> | ||||||
|  |         </item> | ||||||
|  |         <item> | ||||||
|  |          <widget class="QPushButton" name="refresh"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Refreshing</string> | ||||||
|  |           </property> | ||||||
|  |           <property name="enabled"> | ||||||
|  |            <bool>false</bool> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item> | ||||||
|  |          <widget class="QPushButton" name="unban"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Unban</string> | ||||||
|  |           </property> | ||||||
|  |           <property name="enabled"> | ||||||
|  |            <bool>false</bool> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |        </layout> | ||||||
|  |       </item> | ||||||
|  |       <item> | ||||||
|  |        <widget class="QTreeView" name="ban_list_view"/> | ||||||
|  |       </item> | ||||||
|  |      </layout> | ||||||
|  |     </widget> | ||||||
|  |    </item> | ||||||
|  |    <item> | ||||||
|  |     <widget class="QDialogButtonBox" name="buttonBox"> | ||||||
|  |      <property name="standardButtons"> | ||||||
|  |       <set>QDialogButtonBox::Ok</set> | ||||||
|  |      </property> | ||||||
|  |     </widget> | ||||||
|  |    </item> | ||||||
|  |   </layout> | ||||||
|  |  </widget> | ||||||
|  |  <connections> | ||||||
|  |   <connection> | ||||||
|  |    <sender>buttonBox</sender> | ||||||
|  |    <signal>accepted()</signal> | ||||||
|  |    <receiver>ModerationDialog</receiver> | ||||||
|  |    <slot>accept()</slot> | ||||||
|  |   </connection> | ||||||
|  |  </connections> | ||||||
|  |  <resources/> | ||||||
|  | </ui> | ||||||
|  | @ -226,6 +226,12 @@ void MultiplayerState::OnOpenNetworkRoom() { | ||||||
|             if (client_room == nullptr) { |             if (client_room == nullptr) { | ||||||
|                 client_room = new ClientRoomWindow(this); |                 client_room = new ClientRoomWindow(this); | ||||||
|             } |             } | ||||||
|  |             const std::string host_username = member->GetRoomInformation().host_username; | ||||||
|  |             if (host_username.empty()) { | ||||||
|  |                 client_room->SetModPerms(false); | ||||||
|  |             } else { | ||||||
|  |                 client_room->SetModPerms(member->GetUsername() == host_username); | ||||||
|  |             } | ||||||
|             BringWidgetToFront(client_room); |             BringWidgetToFront(client_room); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -66,6 +66,7 @@ private: | ||||||
|     QAction* show_room; |     QAction* show_room; | ||||||
|     std::shared_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session; |     std::shared_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session; | ||||||
|     Network::RoomMember::State current_state = Network::RoomMember::State::Uninitialized; |     Network::RoomMember::State current_state = Network::RoomMember::State::Uninitialized; | ||||||
|  |     bool has_mod_perms = false; | ||||||
|     Network::RoomMember::CallbackHandle<Network::RoomMember::State> state_callback_handle; |     Network::RoomMember::CallbackHandle<Network::RoomMember::State> state_callback_handle; | ||||||
|     Network::RoomMember::CallbackHandle<Network::RoomMember::Error> error_callback_handle; |     Network::RoomMember::CallbackHandle<Network::RoomMember::Error> error_callback_handle; | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue