@@ -28,6 +28,8 @@ ChannelListTree::ChannelListTree()
2828#endif
2929 , m_menu_voice_channel_join(" _Join" , true )
3030 , m_menu_voice_channel_disconnect(" _Disconnect" , true )
31+ , m_menu_voice_stage_join(" _Join" , true )
32+ , m_menu_voice_stage_disconnect(" _Disconnect" , true )
3133 , m_menu_voice_channel_mark_as_read(" Mark as _Read" , true )
3234 , m_menu_voice_open_chat(" Open _Chat" , true )
3335 , m_menu_dm_copy_id(" _Copy ID" , true )
@@ -225,6 +227,21 @@ ChannelListTree::ChannelListTree()
225227 m_menu_voice_channel.append (m_menu_voice_open_chat);
226228 m_menu_voice_channel.show_all ();
227229
230+ #ifdef WITH_VOICE
231+ m_menu_voice_stage_join.signal_activate ().connect ([this ]() {
232+ const auto id = static_cast <Snowflake>((*m_model->get_iter (m_path_for_menu))[m_columns.m_id ]);
233+ m_signal_action_join_voice_channel.emit (id);
234+ });
235+
236+ m_menu_voice_stage_disconnect.signal_activate ().connect ([this ]() {
237+ m_signal_action_disconnect_voice.emit ();
238+ });
239+ #endif
240+
241+ m_menu_voice_stage.append (m_menu_voice_stage_join);
242+ m_menu_voice_stage.append (m_menu_voice_stage_disconnect);
243+ m_menu_voice_stage.show_all ();
244+
228245 m_menu_dm_copy_id.signal_activate ().connect ([this ] {
229246 Gtk::Clipboard::get ()->set_text (std::to_string ((*m_model->get_iter (m_path_for_menu))[m_columns.m_id ]));
230247 });
@@ -366,8 +383,8 @@ int ChannelListTree::SortFunc(const Gtk::TreeModel::iterator &a, const Gtk::Tree
366383 const int64_t b_sort = (*b)[m_columns.m_sort ];
367384 if (a_type == RenderType::DMHeader) return -1 ;
368385 if (b_type == RenderType::DMHeader) return 1 ;
369- if (a_type == RenderType::TextChannel && b_type == RenderType::VoiceChannel) return -1 ;
370- if (b_type == RenderType::TextChannel && a_type == RenderType::VoiceChannel) return 1 ;
386+ if (a_type == RenderType::TextChannel && ( b_type == RenderType::VoiceChannel || b_type == RenderType::VoiceStage) ) return -1 ;
387+ if (b_type == RenderType::TextChannel && ( a_type == RenderType::VoiceChannel || a_type == RenderType::VoiceStage) ) return 1 ;
371388 return static_cast <int >(std::clamp (a_sort - b_sort, int64_t (-1 ), int64_t (1 )));
372389}
373390
@@ -634,6 +651,7 @@ void ChannelListTree::OnThreadListSync(const ThreadListSyncData &data) {
634651
635652void ChannelListTree::OnVoiceUserConnect (Snowflake user_id, Snowflake channel_id) {
636653 auto parent_iter = GetIteratorForRowFromIDOfType (channel_id, RenderType::VoiceChannel);
654+ if (!parent_iter) parent_iter = GetIteratorForRowFromIDOfType (channel_id, RenderType::VoiceStage);
637655 if (!parent_iter) parent_iter = GetIteratorForRowFromIDOfType (channel_id, RenderType::DM);
638656 if (!parent_iter) return ;
639657 const auto user = Abaddon::Get ().GetDiscordClient ().GetUser (user_id);
@@ -914,7 +932,7 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
914932 for (const auto &channel_ : *guild.Channels ) {
915933 const auto channel = discord.GetChannel (channel_.ID );
916934 if (!channel.has_value ()) continue ;
917- if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS || channel->Type == ChannelType::GUILD_VOICE) {
935+ if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS || channel->Type == ChannelType::GUILD_VOICE || channel-> Type == ChannelType::GUILD_STAGE_VOICE ) {
918936 if (channel->ParentID .has_value ())
919937 categories[*channel->ParentID ].push_back (*channel);
920938 else
@@ -954,6 +972,10 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
954972 if (IsTextChannel (channel.Type )) {
955973 channel_row[m_columns.m_type ] = RenderType::TextChannel;
956974 channel_row[m_columns.m_name ] = " #" + Glib::Markup::escape_text (*channel.Name );
975+ } else if (channel.Type == ChannelType::GUILD_STAGE_VOICE) {
976+ channel_row[m_columns.m_type ] = RenderType::VoiceStage;
977+ channel_row[m_columns.m_name ] = Glib::Markup::escape_text (*channel.Name );
978+ add_voice_participants (channel, channel_row->children ());
957979 } else {
958980 channel_row[m_columns.m_type ] = RenderType::VoiceChannel;
959981 channel_row[m_columns.m_name ] = Glib::Markup::escape_text (*channel.Name );
@@ -983,6 +1005,10 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
9831005 if (IsTextChannel (channel.Type )) {
9841006 channel_row[m_columns.m_type ] = RenderType::TextChannel;
9851007 channel_row[m_columns.m_name ] = " #" + Glib::Markup::escape_text (*channel.Name );
1008+ } else if (channel.Type == ChannelType::GUILD_STAGE_VOICE) {
1009+ channel_row[m_columns.m_type ] = RenderType::VoiceStage;
1010+ channel_row[m_columns.m_name ] = Glib::Markup::escape_text (*channel.Name );
1011+ add_voice_participants (channel, channel_row->children ());
9861012 } else {
9871013 channel_row[m_columns.m_type ] = RenderType::VoiceChannel;
9881014 channel_row[m_columns.m_name ] = Glib::Markup::escape_text (*channel.Name );
@@ -1033,7 +1059,7 @@ Gtk::TreeModel::iterator ChannelListTree::CreateVoiceParticipantRow(const UserDa
10331059
10341060 const auto voice_state = Abaddon::Get ().GetDiscordClient ().GetVoiceState (user.ID );
10351061 if (voice_state.has_value ()) {
1036- row[m_columns.m_voice_flags ] = voice_state->second ;
1062+ row[m_columns.m_voice_flags ] = voice_state->second . Flags ;
10371063 }
10381064
10391065 auto &img = Abaddon::Get ().GetImageManager ();
@@ -1331,6 +1357,10 @@ bool ChannelListTree::OnButtonPressEvent(GdkEventButton *ev) {
13311357 OnVoiceChannelSubmenuPopup ();
13321358 m_menu_voice_channel.popup_at_pointer (reinterpret_cast <GdkEvent *>(ev));
13331359 break ;
1360+ case RenderType::VoiceStage:
1361+ OnVoiceStageSubmenuPopup ();
1362+ m_menu_voice_stage.popup_at_pointer (reinterpret_cast <GdkEvent *>(ev));
1363+ break ;
13341364 case RenderType::DM: {
13351365 OnDMSubmenuPopup ();
13361366 const auto channel = Abaddon::Get ().GetDiscordClient ().GetChannel (static_cast <Snowflake>(row[m_columns.m_id ]));
@@ -1442,6 +1472,25 @@ void ChannelListTree::OnVoiceChannelSubmenuPopup() {
14421472#endif
14431473}
14441474
1475+ void ChannelListTree::OnVoiceStageSubmenuPopup () {
1476+ #ifdef WITH_VOICE
1477+ const auto iter = m_model->get_iter (m_path_for_menu);
1478+ if (!iter) return ;
1479+ const auto id = static_cast <Snowflake>((*iter)[m_columns.m_id ]);
1480+ auto &discord = Abaddon::Get ().GetDiscordClient ();
1481+ if (discord.IsVoiceConnected () || discord.IsVoiceConnecting ()) {
1482+ m_menu_voice_stage_join.set_sensitive (false );
1483+ m_menu_voice_stage_disconnect.set_sensitive (discord.GetVoiceChannelID () == id);
1484+ } else {
1485+ m_menu_voice_stage_join.set_sensitive (true );
1486+ m_menu_voice_stage_disconnect.set_sensitive (false );
1487+ }
1488+ #else
1489+ m_menu_voice_stage_join.set_sensitive (false );
1490+ m_menu_voice_stage_disconnect.set_sensitive (false );
1491+ #endif
1492+ }
1493+
14451494void ChannelListTree::OnDMSubmenuPopup () {
14461495 auto iter = m_model->get_iter (m_path_for_menu);
14471496 if (!iter) return ;
0 commit comments