show voice channels and participants even if compiled without audio

This commit is contained in:
ouwou 2024-06-17 03:50:50 -04:00
parent f8de54e47e
commit eb9ad703be
6 changed files with 75 additions and 127 deletions

View File

@ -122,12 +122,10 @@ void CellRendererChannels::get_preferred_width_vfunc(Gtk::Widget &widget, int &m
return get_preferred_width_vfunc_channel(widget, minimum_width, natural_width);
case RenderType::Thread:
return get_preferred_width_vfunc_thread(widget, minimum_width, natural_width);
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
return get_preferred_width_vfunc_voice_channel(widget, minimum_width, natural_width);
case RenderType::VoiceParticipant:
return get_preferred_width_vfunc_voice_participant(widget, minimum_width, natural_width);
#endif
case RenderType::DMHeader:
return get_preferred_width_vfunc_dmheader(widget, minimum_width, natural_width);
case RenderType::DM:
@ -147,12 +145,10 @@ void CellRendererChannels::get_preferred_width_for_height_vfunc(Gtk::Widget &wid
return get_preferred_width_for_height_vfunc_channel(widget, height, minimum_width, natural_width);
case RenderType::Thread:
return get_preferred_width_for_height_vfunc_thread(widget, height, minimum_width, natural_width);
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
return get_preferred_width_for_height_vfunc_voice_channel(widget, height, minimum_width, natural_width);
case RenderType::VoiceParticipant:
return get_preferred_width_for_height_vfunc_voice_participant(widget, height, minimum_width, natural_width);
#endif
case RenderType::DMHeader:
return get_preferred_width_for_height_vfunc_dmheader(widget, height, minimum_width, natural_width);
case RenderType::DM:
@ -172,12 +168,10 @@ void CellRendererChannels::get_preferred_height_vfunc(Gtk::Widget &widget, int &
return get_preferred_height_vfunc_channel(widget, minimum_height, natural_height);
case RenderType::Thread:
return get_preferred_height_vfunc_thread(widget, minimum_height, natural_height);
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
return get_preferred_height_vfunc_voice_channel(widget, minimum_height, natural_height);
case RenderType::VoiceParticipant:
return get_preferred_height_vfunc_voice_participant(widget, minimum_height, natural_height);
#endif
case RenderType::DMHeader:
return get_preferred_height_vfunc_dmheader(widget, minimum_height, natural_height);
case RenderType::DM:
@ -197,12 +191,10 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc(Gtk::Widget &wid
return get_preferred_height_for_width_vfunc_channel(widget, width, minimum_height, natural_height);
case RenderType::Thread:
return get_preferred_height_for_width_vfunc_thread(widget, width, minimum_height, natural_height);
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
return get_preferred_height_for_width_vfunc_voice_channel(widget, width, minimum_height, natural_height);
case RenderType::VoiceParticipant:
return get_preferred_height_for_width_vfunc_voice_participant(widget, width, minimum_height, natural_height);
#endif
case RenderType::DMHeader:
return get_preferred_height_for_width_vfunc_dmheader(widget, width, minimum_height, natural_height);
case RenderType::DM:
@ -222,12 +214,10 @@ void CellRendererChannels::render_vfunc(const Cairo::RefPtr<Cairo::Context> &cr,
return render_vfunc_channel(cr, widget, background_area, cell_area, flags);
case RenderType::Thread:
return render_vfunc_thread(cr, widget, background_area, cell_area, flags);
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
return render_vfunc_voice_channel(cr, widget, background_area, cell_area, flags);
case RenderType::VoiceParticipant:
return render_vfunc_voice_participant(cr, widget, background_area, cell_area, flags);
#endif
case RenderType::DMHeader:
return render_vfunc_dmheader(cr, widget, background_area, cell_area, flags);
case RenderType::DM:
@ -563,8 +553,6 @@ void CellRendererChannels::render_vfunc_thread(const Cairo::RefPtr<Cairo::Contex
}
}
#ifdef WITH_VOICE
// voice channel
void CellRendererChannels::get_preferred_width_vfunc_voice_channel(Gtk::Widget &widget, int &minimum_width, int &natural_width) const {
@ -714,8 +702,6 @@ void CellRendererChannels::render_vfunc_voice_participant(const Cairo::RefPtr<Ca
}
}
#endif
// dm header
void CellRendererChannels::get_preferred_width_vfunc_dmheader(Gtk::Widget &widget, int &minimum_width, int &natural_width) const {

View File

@ -15,12 +15,8 @@ enum class RenderType : uint8_t {
Category,
TextChannel,
Thread,
// TODO: maybe enable anyways but without ability to join if no voice support
#ifdef WITH_VOICE
VoiceChannel,
VoiceParticipant,
#endif
DMHeader,
DM,
@ -107,7 +103,6 @@ protected:
const Gdk::Rectangle &cell_area,
Gtk::CellRendererState flags);
#ifdef WITH_VOICE
// voice channel
void get_preferred_width_vfunc_voice_channel(Gtk::Widget &widget, int &minimum_width, int &natural_width) const;
void get_preferred_width_for_height_vfunc_voice_channel(Gtk::Widget &widget, int height, int &minimum_width, int &natural_width) const;
@ -129,7 +124,6 @@ protected:
const Gdk::Rectangle &background_area,
const Gdk::Rectangle &cell_area,
Gtk::CellRendererState flags);
#endif
// dm header
void get_preferred_width_vfunc_dmheader(Gtk::Widget &widget, int &minimum_width, int &natural_width) const;

View File

@ -26,11 +26,9 @@ ChannelListTree::ChannelListTree()
, m_menu_channel_open_tab("Open in New _Tab", true)
, m_menu_dm_open_tab("Open in New _Tab", true)
#endif
#ifdef WITH_VOICE
, m_menu_voice_channel_join("_Join", true)
, m_menu_voice_channel_disconnect("_Disconnect", true)
, m_menu_voice_open_chat("Open _Chat", true)
#endif
, m_menu_dm_copy_id("_Copy ID", true)
, m_menu_dm_close("") // changes depending on if group or not
#ifdef WITH_VOICE
@ -209,6 +207,7 @@ ChannelListTree::ChannelListTree()
m_menu_voice_channel_disconnect.signal_activate().connect([this]() {
m_signal_action_disconnect_voice.emit();
});
#endif
m_menu_voice_open_chat.signal_activate().connect([this]() {
const auto id = static_cast<Snowflake>((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]);
@ -219,7 +218,6 @@ ChannelListTree::ChannelListTree()
m_menu_voice_channel.append(m_menu_voice_channel_disconnect);
m_menu_voice_channel.append(m_menu_voice_open_chat);
m_menu_voice_channel.show_all();
#endif
m_menu_dm_copy_id.signal_activate().connect([this] {
Gtk::Clipboard::get()->set_text(std::to_string((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]));
@ -362,10 +360,8 @@ int ChannelListTree::SortFunc(const Gtk::TreeModel::iterator &a, const Gtk::Tree
const int64_t b_sort = (*b)[m_columns.m_sort];
if (a_type == RenderType::DMHeader) return -1;
if (b_type == RenderType::DMHeader) return 1;
#ifdef WITH_VOICE
if (a_type == RenderType::TextChannel && b_type == RenderType::VoiceChannel) return -1;
if (b_type == RenderType::TextChannel && a_type == RenderType::VoiceChannel) return 1;
#endif
return static_cast<int>(std::clamp(a_sort - b_sort, int64_t(-1), int64_t(1)));
}
@ -497,13 +493,9 @@ void ChannelListTree::UpdateChannel(Snowflake id) {
auto channel = Abaddon::Get().GetDiscordClient().GetChannel(id);
if (!iter || !channel.has_value()) return;
if (channel->Type == ChannelType::GUILD_CATEGORY) return UpdateChannelCategory(*channel);
// TODO: theres like 4 different fucking ways of checking if somethin g is text or voice can i fix that How stupid .
// fun fact clang-format is indenting me right now i wonder why ,,,,,,,,,,,
#ifdef WITH_VOICE
// TODO: theres like 4 different fucking ways of checking if somethin g is text or voice can i fix that How stupid .
// fun fact clang-format is indenting me right now i wonder why ,,,,,,,,,,,
if (!channel->IsText() && channel->Type != ChannelType::GUILD_VOICE) return;
#else
if (!channel->IsText()) return;
#endif
// refresh stuff that might have changed
const bool is_orphan_TMP = !channel->ParentID.has_value();
@ -525,11 +517,7 @@ void ChannelListTree::UpdateChannel(Snowflake id) {
void ChannelListTree::UpdateCreateChannel(const ChannelData &channel) {
if (channel.Type == ChannelType::GUILD_CATEGORY) return (void)UpdateCreateChannelCategory(channel);
if (channel.Type == ChannelType::DM || channel.Type == ChannelType::GROUP_DM) return UpdateCreateDMChannel(channel);
#ifdef WITH_VOICE
if (channel.Type != ChannelType::GUILD_TEXT && channel.Type != ChannelType::GUILD_NEWS && channel.Type != ChannelType::GUILD_VOICE) return;
#else
if (channel.Type != ChannelType::GUILD_TEXT && channel.Type != ChannelType::GUILD_NEWS) return;
#endif
Gtk::TreeRow channel_row;
bool orphan;
@ -542,11 +530,7 @@ void ChannelListTree::UpdateCreateChannel(const ChannelData &channel) {
auto iter = GetIteratorForGuildFromID(*channel.GuildID);
channel_row = *m_model->append(iter->children());
}
#ifdef WITH_VOICE
channel_row[m_columns.m_type] = IsTextChannel(channel.Type) ? RenderType::TextChannel : RenderType::VoiceChannel;
#else
channel_row[m_columns.m_type] = RenderType::TextChannel;
#endif
channel_row[m_columns.m_id] = channel.ID;
channel_row[m_columns.m_name] = "#" + Glib::Markup::escape_text(*channel.Name);
channel_row[m_columns.m_nsfw] = channel.NSFW();
@ -642,7 +626,6 @@ void ChannelListTree::OnThreadListSync(const ThreadListSyncData &data) {
}
}
#ifdef WITH_VOICE
void ChannelListTree::OnVoiceUserConnect(Snowflake user_id, Snowflake channel_id) {
auto parent_iter = GetIteratorForRowFromIDOfType(channel_id, RenderType::VoiceChannel);
if (!parent_iter) parent_iter = GetIteratorForRowFromIDOfType(channel_id, RenderType::DM);
@ -664,7 +647,6 @@ void ChannelListTree::OnVoiceStateSet(Snowflake user_id, Snowflake channel_id, V
(*iter)[m_columns.m_voice_flags] = flags;
}
}
#endif
void ChannelListTree::DeleteThreadRow(Snowflake id) {
auto iter = GetIteratorForRowFromID(id);
@ -926,11 +908,7 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
for (const auto &channel_ : *guild.Channels) {
const auto channel = discord.GetChannel(channel_.ID);
if (!channel.has_value()) continue;
#ifdef WITH_VOICE
if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS || channel->Type == ChannelType::GUILD_VOICE) {
#else
if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS) {
#endif
if (channel->ParentID.has_value())
categories[*channel->ParentID].push_back(*channel);
else
@ -957,7 +935,6 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
}
};
#ifdef WITH_VOICE
auto add_voice_participants = [this, &discord](const ChannelData &channel, const Gtk::TreeNodeChildren &root) {
for (auto user_id : discord.GetUsersInVoiceChannel(channel.ID)) {
if (const auto user = discord.GetUser(user_id); user.has_value()) {
@ -965,21 +942,17 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
}
}
};
#endif
for (const auto &channel : orphan_channels) {
auto channel_row = *m_model->append(guild_row.children());
if (IsTextChannel(channel.Type)) {
channel_row[m_columns.m_type] = RenderType::TextChannel;
channel_row[m_columns.m_name] = "#" + Glib::Markup::escape_text(*channel.Name);
}
#ifdef WITH_VOICE
else {
} else {
channel_row[m_columns.m_type] = RenderType::VoiceChannel;
channel_row[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
add_voice_participants(channel, channel_row->children());
}
#endif
channel_row[m_columns.m_id] = channel.ID;
channel_row[m_columns.m_sort] = *channel.Position + OrphanChannelSortOffset;
channel_row[m_columns.m_nsfw] = channel.NSFW();
@ -1004,14 +977,11 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
if (IsTextChannel(channel.Type)) {
channel_row[m_columns.m_type] = RenderType::TextChannel;
channel_row[m_columns.m_name] = "#" + Glib::Markup::escape_text(*channel.Name);
}
#ifdef WITH_VOICE
else {
} else {
channel_row[m_columns.m_type] = RenderType::VoiceChannel;
channel_row[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
add_voice_participants(channel, channel_row->children());
}
#endif
channel_row[m_columns.m_id] = channel.ID;
channel_row[m_columns.m_sort] = *channel.Position;
channel_row[m_columns.m_nsfw] = channel.NSFW();
@ -1049,7 +1019,6 @@ Gtk::TreeModel::iterator ChannelListTree::CreateThreadRow(const Gtk::TreeNodeChi
return thread_iter;
}
#ifdef WITH_VOICE
Gtk::TreeModel::iterator ChannelListTree::CreateVoiceParticipantRow(const UserData &user, const Gtk::TreeNodeChildren &parent) {
auto row = *m_model->append(parent);
row[m_columns.m_type] = RenderType::VoiceParticipant;
@ -1071,7 +1040,6 @@ Gtk::TreeModel::iterator ChannelListTree::CreateVoiceParticipantRow(const UserDa
return row;
}
#endif
void ChannelListTree::UpdateChannelCategory(const ChannelData &channel) {
auto iter = GetIteratorForRowFromID(channel.ID);
@ -1215,13 +1183,11 @@ void ChannelListTree::AddPrivateChannels() {
row[m_columns.m_icon] = img.GetPlaceholder(DMIconSize);
row[m_columns.m_expanded] = true;
#ifdef WITH_VOICE
for (auto user_id : discord.GetUsersInVoiceChannel(dm_id)) {
if (const auto user = discord.GetUser(user_id); user.has_value()) {
CreateVoiceParticipantRow(*user, row->children());
}
}
#endif
SetDMChannelIcon(iter, *dm);
}
@ -1352,12 +1318,10 @@ bool ChannelListTree::OnButtonPressEvent(GdkEventButton *ev) {
OnChannelSubmenuPopup();
m_menu_channel.popup_at_pointer(reinterpret_cast<GdkEvent *>(ev));
break;
#ifdef WITH_VOICE
case RenderType::VoiceChannel:
OnVoiceChannelSubmenuPopup();
m_menu_voice_channel.popup_at_pointer(reinterpret_cast<GdkEvent *>(ev));
break;
#endif
case RenderType::DM: {
OnDMSubmenuPopup();
const auto channel = Abaddon::Get().GetDiscordClient().GetChannel(static_cast<Snowflake>(row[m_columns.m_id]));
@ -1450,8 +1414,8 @@ void ChannelListTree::OnChannelSubmenuPopup() {
m_menu_channel_toggle_mute.set_label("Mute");
}
#ifdef WITH_VOICE
void ChannelListTree::OnVoiceChannelSubmenuPopup() {
#ifdef WITH_VOICE
const auto iter = m_model->get_iter(m_path_for_menu);
if (!iter) return;
const auto id = static_cast<Snowflake>((*iter)[m_columns.m_id]);
@ -1463,8 +1427,11 @@ void ChannelListTree::OnVoiceChannelSubmenuPopup() {
m_menu_voice_channel_join.set_sensitive(true);
m_menu_voice_channel_disconnect.set_sensitive(false);
}
}
#else
m_menu_voice_channel_join.set_sensitive(false);
m_menu_voice_channel_disconnect.set_sensitive(false);
#endif
}
void ChannelListTree::OnDMSubmenuPopup() {
auto iter = m_model->get_iter(m_path_for_menu);

View File

@ -104,10 +104,7 @@ protected:
Gtk::TreeModel::iterator AddGuild(const GuildData &guild, const Gtk::TreeNodeChildren &root);
Gtk::TreeModel::iterator UpdateCreateChannelCategory(const ChannelData &channel);
Gtk::TreeModel::iterator CreateThreadRow(const Gtk::TreeNodeChildren &children, const ChannelData &channel);
#ifdef WITH_VOICE
Gtk::TreeModel::iterator CreateVoiceParticipantRow(const UserData &user, const Gtk::TreeNodeChildren &parent);
#endif
void UpdateChannelCategory(const ChannelData &channel);
@ -162,12 +159,10 @@ protected:
Gtk::MenuItem m_menu_channel_open_tab;
#endif
#ifdef WITH_VOICE
Gtk::Menu m_menu_voice_channel;
Gtk::MenuItem m_menu_voice_channel_join;
Gtk::MenuItem m_menu_voice_channel_disconnect;
Gtk::MenuItem m_menu_voice_open_chat;
#endif
Gtk::Menu m_menu_dm;
Gtk::MenuItem m_menu_dm_copy_id;
@ -195,10 +190,7 @@ protected:
void OnChannelSubmenuPopup();
void OnDMSubmenuPopup();
void OnThreadSubmenuPopup();
#ifdef WITH_VOICE
void OnVoiceChannelSubmenuPopup();
#endif
bool m_updating_listing = false;

View File

@ -1284,21 +1284,10 @@ Snowflake DiscordClient::GetVoiceChannelID() const noexcept {
return m_voice_channel_id;
}
std::unordered_set<Snowflake> DiscordClient::GetUsersInVoiceChannel(Snowflake channel_id) {
return m_voice_state_channel_users[channel_id];
}
std::optional<uint32_t> DiscordClient::GetSSRCOfUser(Snowflake id) const {
return m_voice.GetSSRCOfUser(id);
}
std::optional<std::pair<Snowflake, VoiceStateFlags>> DiscordClient::GetVoiceState(Snowflake user_id) const {
if (const auto it = m_voice_states.find(user_id); it != m_voice_states.end()) {
return it->second;
}
return std::nullopt;
}
DiscordVoiceClient &DiscordClient::GetVoiceClient() {
return m_voice;
}
@ -1314,6 +1303,17 @@ void DiscordClient::SetVoiceDeafened(bool is_deaf) {
}
#endif
std::optional<std::pair<Snowflake, VoiceStateFlags>> DiscordClient::GetVoiceState(Snowflake user_id) const {
if (const auto it = m_voice_states.find(user_id); it != m_voice_states.end()) {
return it->second;
}
return std::nullopt;
}
std::unordered_set<Snowflake> DiscordClient::GetUsersInVoiceChannel(Snowflake channel_id) {
return m_voice_state_channel_users[channel_id];
}
void DiscordClient::SetReferringChannel(Snowflake id) {
if (!id.IsValid()) {
m_http.SetPersistentHeader("Referer", "https://discord.com/channels/@me");
@ -1652,10 +1652,10 @@ void DiscordClient::HandleGatewayMessage(std::string str) {
case GatewayEvent::GUILD_MEMBERS_CHUNK: {
HandleGatewayGuildMembersChunk(m);
} break;
#ifdef WITH_VOICE
case GatewayEvent::VOICE_STATE_UPDATE: {
HandleGatewayVoiceStateUpdate(m);
} break;
#ifdef WITH_VOICE
case GatewayEvent::VOICE_SERVER_UPDATE: {
HandleGatewayVoiceServerUpdate(m);
} break;
@ -2336,12 +2336,6 @@ void DiscordClient::HandleGatewayGuildMembersChunk(const GatewayMessage &msg) {
*
*/
void DiscordClient::HandleGatewayVoiceStateUpdate(const GatewayMessage &msg) {
spdlog::get("discord")->trace("VOICE_STATE_UPDATE");
CheckVoiceState(msg.Data);
}
void DiscordClient::HandleGatewayVoiceServerUpdate(const GatewayMessage &msg) {
spdlog::get("discord")->trace("VOICE_SERVER_UPDATE");
@ -2371,8 +2365,17 @@ void DiscordClient::HandleGatewayCallCreate(const GatewayMessage &msg) {
}
}
#endif
void DiscordClient::HandleGatewayVoiceStateUpdate(const GatewayMessage &msg) {
spdlog::get("discord")->trace("VOICE_STATE_UPDATE");
CheckVoiceState(msg.Data);
}
void DiscordClient::CheckVoiceState(const VoiceState &data) {
if (data.UserID == m_user_data.ID) {
#ifdef WITH_VOICE
spdlog::get("discord")->debug("Voice session ID: {}", data.SessionID);
m_voice.SetSessionID(data.SessionID);
@ -2383,6 +2386,7 @@ void DiscordClient::CheckVoiceState(const VoiceState &data) {
m_voice_channel_id = *data.ChannelID;
m_signal_voice_channel_changed.emit(m_voice_channel_id);
}
#endif
} else {
if (data.GuildID.has_value() && data.Member.has_value()) {
if (data.Member->User.has_value()) {
@ -2409,7 +2413,6 @@ void DiscordClient::CheckVoiceState(const VoiceState &data) {
}
}
}
#endif
void DiscordClient::HandleGatewayReadySupplemental(const GatewayMessage &msg) {
ReadySupplementalData data = msg.Data;
@ -2929,6 +2932,15 @@ void DiscordClient::SendVoiceStateUpdate() {
m_websocket.Send(msg);
}
void DiscordClient::OnVoiceConnected() {
m_signal_voice_connected.emit();
}
void DiscordClient::OnVoiceDisconnected() {
m_signal_voice_disconnected.emit();
}
#endif
void DiscordClient::SetVoiceState(Snowflake user_id, const VoiceState &state) {
if (!state.ChannelID.has_value()) {
spdlog::get("discord")->error("SetVoiceState called with missing channel ID");
@ -2958,15 +2970,6 @@ void DiscordClient::ClearVoiceState(Snowflake user_id) {
}
}
void DiscordClient::OnVoiceConnected() {
m_signal_voice_connected.emit();
}
void DiscordClient::OnVoiceDisconnected() {
m_signal_voice_disconnected.emit();
}
#endif
void DiscordClient::LoadEventMap() {
m_event_map["READY"] = GatewayEvent::READY;
m_event_map["MESSAGE_CREATE"] = GatewayEvent::MESSAGE_CREATE;
@ -3242,14 +3245,6 @@ DiscordClient::type_signal_voice_speaking DiscordClient::signal_voice_speaking()
return m_signal_voice_speaking;
}
DiscordClient::type_signal_voice_user_disconnect DiscordClient::signal_voice_user_disconnect() {
return m_signal_voice_user_disconnect;
}
DiscordClient::type_signal_voice_user_connect DiscordClient::signal_voice_user_connect() {
return m_signal_voice_user_connect;
}
DiscordClient::type_signal_voice_requested_connect DiscordClient::signal_voice_requested_connect() {
return m_signal_voice_requested_connect;
}
@ -3265,8 +3260,16 @@ DiscordClient::type_signal_voice_client_state_update DiscordClient::signal_voice
DiscordClient::type_signal_voice_channel_changed DiscordClient::signal_voice_channel_changed() {
return m_signal_voice_channel_changed;
}
#endif
DiscordClient::type_signal_voice_user_disconnect DiscordClient::signal_voice_user_disconnect() {
return m_signal_voice_user_disconnect;
}
DiscordClient::type_signal_voice_user_connect DiscordClient::signal_voice_user_connect() {
return m_signal_voice_user_connect;
}
DiscordClient::type_signal_voice_state_set DiscordClient::signal_voice_state_set() {
return m_signal_voice_state_set;
}
#endif

View File

@ -200,9 +200,7 @@ public:
[[nodiscard]] bool IsVoiceConnected() const noexcept;
[[nodiscard]] bool IsVoiceConnecting() const noexcept;
[[nodiscard]] Snowflake GetVoiceChannelID() const noexcept;
[[nodiscard]] std::unordered_set<Snowflake> GetUsersInVoiceChannel(Snowflake channel_id);
[[nodiscard]] std::optional<uint32_t> GetSSRCOfUser(Snowflake id) const;
[[nodiscard]] std::optional<std::pair<Snowflake, VoiceStateFlags>> GetVoiceState(Snowflake user_id) const;
DiscordVoiceClient &GetVoiceClient();
@ -210,6 +208,9 @@ public:
void SetVoiceDeafened(bool is_deaf);
#endif
[[nodiscard]] std::optional<std::pair<Snowflake, VoiceStateFlags>> GetVoiceState(Snowflake user_id) const;
[[nodiscard]] std::unordered_set<Snowflake> GetUsersInVoiceChannel(Snowflake channel_id);
void SetReferringChannel(Snowflake id);
void SetBuildNumber(uint32_t build_number);
@ -299,12 +300,13 @@ private:
void HandleGatewayInvalidSession(const GatewayMessage &msg);
#ifdef WITH_VOICE
void HandleGatewayVoiceStateUpdate(const GatewayMessage &msg);
void HandleGatewayVoiceServerUpdate(const GatewayMessage &msg);
void HandleGatewayCallCreate(const GatewayMessage &msg);
#endif
void HandleGatewayVoiceStateUpdate(const GatewayMessage &msg);
void CheckVoiceState(const VoiceState &data);
#endif
void HeartbeatThread();
void SendIdentify();
@ -375,19 +377,20 @@ private:
bool m_deaf_requested = false;
Snowflake m_voice_channel_id;
// todo sql i guess
std::unordered_map<Snowflake, std::pair<Snowflake, VoiceStateFlags>> m_voice_states;
std::unordered_map<Snowflake, std::unordered_set<Snowflake>> m_voice_state_channel_users;
void SendVoiceStateUpdate();
void SetVoiceState(Snowflake user_id, const VoiceState &state);
void ClearVoiceState(Snowflake user_id);
void OnVoiceConnected();
void OnVoiceDisconnected();
#endif
void SetVoiceState(Snowflake user_id, const VoiceState &state);
void ClearVoiceState(Snowflake user_id);
// todo sql i guess
std::unordered_map<Snowflake, std::pair<Snowflake, VoiceStateFlags>> m_voice_states;
std::unordered_map<Snowflake, std::unordered_set<Snowflake>> m_voice_state_channel_users;
mutable std::mutex m_msg_mutex;
Glib::Dispatcher m_msg_dispatch;
std::queue<std::string> m_msg_queue;
@ -465,15 +468,16 @@ public:
using type_signal_voice_connected = sigc::signal<void()>;
using type_signal_voice_disconnected = sigc::signal<void()>;
using type_signal_voice_speaking = sigc::signal<void(VoiceSpeakingData)>;
using type_signal_voice_user_disconnect = sigc::signal<void(Snowflake, Snowflake)>;
using type_signal_voice_user_connect = sigc::signal<void(Snowflake, Snowflake)>;
using type_signal_voice_requested_connect = sigc::signal<void(Snowflake)>;
using type_signal_voice_requested_disconnect = sigc::signal<void()>;
using type_signal_voice_client_state_update = sigc::signal<void(DiscordVoiceClient::State)>;
using type_signal_voice_channel_changed = sigc::signal<void(Snowflake)>;
using type_signal_voice_state_set = sigc::signal<void(Snowflake, Snowflake, VoiceStateFlags)>;
#endif
using type_signal_voice_user_disconnect = sigc::signal<void(Snowflake, Snowflake)>;
using type_signal_voice_user_connect = sigc::signal<void(Snowflake, Snowflake)>;
using type_signal_voice_state_set = sigc::signal<void(Snowflake, Snowflake, VoiceStateFlags)>;
type_signal_gateway_ready signal_gateway_ready();
type_signal_gateway_ready_supplemental signal_gateway_ready_supplemental();
type_signal_message_create signal_message_create();
@ -533,15 +537,16 @@ public:
type_signal_voice_connected signal_voice_connected();
type_signal_voice_disconnected signal_voice_disconnected();
type_signal_voice_speaking signal_voice_speaking();
type_signal_voice_user_disconnect signal_voice_user_disconnect();
type_signal_voice_user_connect signal_voice_user_connect();
type_signal_voice_requested_connect signal_voice_requested_connect();
type_signal_voice_requested_disconnect signal_voice_requested_disconnect();
type_signal_voice_client_state_update signal_voice_client_state_update();
type_signal_voice_channel_changed signal_voice_channel_changed();
type_signal_voice_state_set signal_voice_state_set();
#endif
type_signal_voice_user_disconnect signal_voice_user_disconnect();
type_signal_voice_user_connect signal_voice_user_connect();
type_signal_voice_state_set signal_voice_state_set();
protected:
type_signal_gateway_ready m_signal_gateway_ready;
type_signal_gateway_ready_supplemental m_signal_gateway_ready_supplemental;
@ -602,12 +607,13 @@ protected:
type_signal_voice_connected m_signal_voice_connected;
type_signal_voice_disconnected m_signal_voice_disconnected;
type_signal_voice_speaking m_signal_voice_speaking;
type_signal_voice_user_disconnect m_signal_voice_user_disconnect;
type_signal_voice_user_connect m_signal_voice_user_connect;
type_signal_voice_requested_connect m_signal_voice_requested_connect;
type_signal_voice_requested_disconnect m_signal_voice_requested_disconnect;
type_signal_voice_client_state_update m_signal_voice_client_state_update;
type_signal_voice_channel_changed m_signal_voice_channel_changed;
type_signal_voice_state_set m_signal_voice_state_set;
#endif
type_signal_voice_user_disconnect m_signal_voice_user_disconnect;
type_signal_voice_user_connect m_signal_voice_user_connect;
type_signal_voice_state_set m_signal_voice_state_set;
};