Merge branch 'master' into classic-channels

This commit is contained in:
ouwou 2023-10-27 01:38:17 -04:00
commit c35d8b4e2d
21 changed files with 109 additions and 39 deletions

View File

@ -299,6 +299,7 @@ For example, memory_db would be set by adding `memory_db = true` under the line
| `save_state` | boolean | true | save the state of the gui (active channels, tabs, expanded channels) | | `save_state` | boolean | true | save the state of the gui (active channels, tabs, expanded channels) |
| `alt_menu` | boolean | false | keep the menu hidden unless revealed with alt key | | `alt_menu` | boolean | false | keep the menu hidden unless revealed with alt key |
| `hide_to_tray` | boolean | false | hide abaddon to the system tray on window close | | `hide_to_tray` | boolean | false | hide abaddon to the system tray on window close |
| `show_deleted_indicator` | boolean | true | show \[deleted\] indicator next to deleted messages instead of actually deleting the message |
| `font_scale` | double | | scale font rendering. 1 is unchanged | | `font_scale` | double | | scale font rendering. 1 is unchanged |
#### style #### style
@ -324,7 +325,13 @@ For example, memory_db would be set by adding `memory_db = true` under the line
| Setting | Type | Default | Description | | Setting | Type | Default | Description |
|---------|--------|------------------------------------|------------------------------------------------------------| |---------|--------|------------------------------------|------------------------------------------------------------|
| vad | string | rnnoise if enabled, gate otherwise | Method used for voice activity detection. Changeable in UI | | `vad` | string | rnnoise if enabled, gate otherwise | Method used for voice activity detection. Changeable in UI |
#### windows
| Setting | Type | Default | Description |
|---------------|---------|---------|-------------------------|
| `hideconsole` | boolean | true | Hide console on startup |
### Environment variables ### Environment variables

BIN
res/res/crunchyroll.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
res/res/ebay.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
res/res/instagram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
res/res/paypal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
res/res/playstation.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
res/res/riotgames.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
res/res/tiktok.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -419,13 +419,23 @@ void AudioManager::OnCapturedPCM(const int16_t *pcm, ma_uint32 frames) {
if (m_opus_buffer == nullptr || !m_should_capture) return; if (m_opus_buffer == nullptr || !m_should_capture) return;
const double gain = m_capture_gain; const double gain = m_capture_gain;
// i have a suspicion i can cast the const away... but i wont
std::vector<int16_t> new_pcm(pcm, pcm + frames * 2); std::vector<int16_t> new_pcm(pcm, pcm + frames * 2);
for (auto &val : new_pcm) { for (auto &val : new_pcm) {
const int32_t unclamped = static_cast<int32_t>(val * gain); const int32_t unclamped = static_cast<int32_t>(val * gain);
val = std::clamp(unclamped, INT16_MIN, INT16_MAX); val = std::clamp(unclamped, INT16_MIN, INT16_MAX);
} }
if (m_mix_mono) {
for (size_t i = 0; i < frames * 2; i += 2) {
const int sample_L = new_pcm[i];
const int sample_R = new_pcm[i + 1];
const int16_t mixed = static_cast<int16_t>((sample_L + sample_R) / 2);
new_pcm[i] = mixed;
new_pcm[i + 1] = mixed;
}
}
UpdateCaptureVolume(new_pcm.data(), frames); UpdateCaptureVolume(new_pcm.data(), frames);
static std::array<float, 480> denoised_L; static std::array<float, 480> denoised_L;
@ -629,6 +639,14 @@ bool AudioManager::GetSuppressNoise() const {
} }
#endif #endif
void AudioManager::SetMixMono(bool value) {
m_mix_mono = value;
}
bool AudioManager::GetMixMono() const {
return m_mix_mono;
}
AudioManager::type_signal_opus_packet AudioManager::signal_opus_packet() { AudioManager::type_signal_opus_packet AudioManager::signal_opus_packet() {
return m_signal_opus_packet; return m_signal_opus_packet;
} }

View File

@ -87,6 +87,9 @@ public:
bool GetSuppressNoise() const; bool GetSuppressNoise() const;
#endif #endif
void SetMixMono(bool value);
bool GetMixMono() const;
private: private:
void OnCapturedPCM(const int16_t *pcm, ma_uint32 frames); void OnCapturedPCM(const int16_t *pcm, ma_uint32 frames);
@ -144,6 +147,7 @@ private:
std::atomic<double> m_prob_threshold = 0.5; std::atomic<double> m_prob_threshold = 0.5;
std::atomic<float> m_vad_prob = 0.0; std::atomic<float> m_vad_prob = 0.0;
std::atomic<bool> m_enable_noise_suppression = false; std::atomic<bool> m_enable_noise_suppression = false;
std::atomic<bool> m_mix_mono = false;
std::unordered_set<uint32_t> m_muted_ssrcs; std::unordered_set<uint32_t> m_muted_ssrcs;
std::unordered_map<uint32_t, double> m_volume_ssrc; std::unordered_map<uint32_t, double> m_volume_ssrc;

View File

@ -187,8 +187,15 @@ void ChatList::DeleteMessage(Snowflake id) {
if (widget == m_id_to_widget.end()) return; if (widget == m_id_to_widget.end()) return;
auto *x = dynamic_cast<ChatMessageItemContainer *>(widget->second); auto *x = dynamic_cast<ChatMessageItemContainer *>(widget->second);
if (x != nullptr)
x->UpdateAttributes(); if (x != nullptr) {
if (Abaddon::Get().GetSettings().ShowDeletedIndicator) {
x->UpdateAttributes();
} else {
RemoveMessageAndHeader(x);
m_id_to_widget.erase(id);
}
}
} }
void ChatList::RefetchMessage(Snowflake id) { void ChatList::RefetchMessage(Snowflake id) {

View File

@ -1057,10 +1057,9 @@ void ChatMessageHeader::UpdateName() {
const auto chan = discord.GetChannel(ChannelID); const auto chan = discord.GetChannel(ChannelID);
bool is_guild = chan.has_value() && chan->GuildID.has_value(); bool is_guild = chan.has_value() && chan->GuildID.has_value();
if (is_guild) { if (is_guild) {
const auto member = discord.GetMember(UserID, *chan->GuildID);
const auto role_id = discord.GetMemberHoistedRole(*chan->GuildID, UserID, true); const auto role_id = discord.GetMemberHoistedRole(*chan->GuildID, UserID, true);
const auto role = discord.GetRole(role_id); const auto role = discord.GetRole(role_id);
const auto name = GetEscapedDisplayName(*user, member); const auto name = user->GetDisplayNameEscaped(*chan->GuildID);
std::string md; std::string md;
if (role.has_value()) if (role.has_value())
@ -1090,13 +1089,6 @@ void ChatMessageHeader::AttachUserMenuHandler(Gtk::Widget &widget) {
}); });
} }
Glib::ustring ChatMessageHeader::GetEscapedDisplayName(const UserData &user, const std::optional<GuildMember> &member) {
if (member.has_value() && !member->Nickname.empty())
return Glib::Markup::escape_text(member->Nickname);
else
return Glib::Markup::escape_text(user.GetDisplayNameEscaped());
}
bool ChatMessageHeader::on_author_button_press(GdkEventButton *ev) { bool ChatMessageHeader::on_author_button_press(GdkEventButton *ev) {
if (ev->button == GDK_BUTTON_PRIMARY && (ev->state & GDK_SHIFT_MASK)) { if (ev->button == GDK_BUTTON_PRIMARY && (ev->state & GDK_SHIFT_MASK)) {
m_signal_action_insert_mention.emit(); m_signal_action_insert_mention.emit();

View File

@ -84,7 +84,6 @@ public:
protected: protected:
void AttachUserMenuHandler(Gtk::Widget &widget); void AttachUserMenuHandler(Gtk::Widget &widget);
static Glib::ustring GetEscapedDisplayName(const UserData &user, const std::optional<GuildMember> &member);
bool on_author_button_press(GdkEventButton *ev); bool on_author_button_press(GdkEventButton *ev);

View File

@ -63,6 +63,7 @@ void SettingsManager::ReadSettings() {
SMBOOL("gui", "unreads", Unreads); SMBOOL("gui", "unreads", Unreads);
SMBOOL("gui", "alt_menu", AltMenu); SMBOOL("gui", "alt_menu", AltMenu);
SMBOOL("gui", "hide_to_tray", HideToTray); SMBOOL("gui", "hide_to_tray", HideToTray);
SMBOOL("gui", "show_deleted_indicator", ShowDeletedIndicator);
SMFLT("gui", "font_scale", FontScale); SMFLT("gui", "font_scale", FontScale);
SMINT("http", "concurrent", CacheHTTPConcurrency); SMINT("http", "concurrent", CacheHTTPConcurrency);
SMSTR("http", "user_agent", UserAgent); SMSTR("http", "user_agent", UserAgent);
@ -153,6 +154,7 @@ void SettingsManager::Close() {
SMBOOL("gui", "unreads", Unreads); SMBOOL("gui", "unreads", Unreads);
SMBOOL("gui", "alt_menu", AltMenu); SMBOOL("gui", "alt_menu", AltMenu);
SMBOOL("gui", "hide_to_tray", HideToTray); SMBOOL("gui", "hide_to_tray", HideToTray);
SMBOOL("gui", "show_deleted_indicator", ShowDeletedIndicator);
SMFLT("gui", "font_scale", FontScale); SMFLT("gui", "font_scale", FontScale);
SMINT("http", "concurrent", CacheHTTPConcurrency); SMINT("http", "concurrent", CacheHTTPConcurrency);
SMSTR("http", "user_agent", UserAgent); SMSTR("http", "user_agent", UserAgent);

View File

@ -30,6 +30,7 @@ public:
bool Unreads { true }; bool Unreads { true };
bool AltMenu { false }; bool AltMenu { false };
bool HideToTray { false }; bool HideToTray { false };
bool ShowDeletedIndicator { true };
double FontScale { -1.0 }; double FontScale { -1.0 };
// [http] // [http]

View File

@ -29,10 +29,22 @@ std::optional<std::pair<std::string, std::string>> ParseCookie(const Glib::ustri
} }
std::optional<Glib::ustring> GetJavascriptFileFromAppPage(const Glib::ustring &contents) { std::optional<Glib::ustring> GetJavascriptFileFromAppPage(const Glib::ustring &contents) {
auto regex = Glib::Regex::create(R"(app-mount.*(/assets/[\w\d]*.js).*/assets/[\w\d]*.js)"); auto regex = Glib::Regex::create(R"(/assets/\w{20}.js)");
std::vector<Glib::ustring> matches;
// regex->match_all doesnt work for some reason
int start_position = 0;
Glib::MatchInfo match; Glib::MatchInfo match;
if (regex->match(contents, match)) { while (regex->match(contents, start_position, match)) {
return match.fetch(1); const auto str = match.fetch(0);
matches.push_back(str);
int foo;
match.fetch_pos(0, start_position, foo);
start_position += str.size();
}
if (matches.size() >= 6) {
return matches[matches.size() - 6];
} }
return {}; return {};
@ -52,7 +64,7 @@ std::optional<uint32_t> GetBuildNumberFromJSURL(const Glib::ustring &url, const
auto res = req.execute(); auto res = req.execute();
if (res.error) return {}; if (res.error) return {};
auto regex = Glib::Regex::create(R"("buildNumber",null!==\(t="(\d+)\"\))"); auto regex = Glib::Regex::create("buildNumber:\"(\\d+)\"");
Glib::MatchInfo match; Glib::MatchInfo match;
Glib::ustring string = res.text; Glib::ustring string = res.text;
if (regex->match(string, match)) { if (regex->match(string, match)) {

View File

@ -1,6 +1,34 @@
#include "userinfopane.hpp" #include "userinfopane.hpp"
#include <unordered_set> #include <unordered_set>
static std::string GetConnectionURL(const ConnectionData &conn) {
if (conn.Type == "github") {
return "https://github.com/" + conn.Name;
} else if (conn.Type == "steam") {
return "https://steamcommunity.com/profiles/" + conn.ID;
} else if (conn.Type == "twitch") {
return "https://twitch.tv/" + conn.Name;
} else if (conn.Type == "twitter") {
return "https://twitter.com/i/user/" + conn.ID;
} else if (conn.Type == "spotify") {
return "https://open.spotify.com/user/" + conn.ID;
} else if (conn.Type == "reddit") {
return "https://reddit.com/u/" + conn.Name;
} else if (conn.Type == "youtube") {
return "https://www.youtube.com/channel/" + conn.ID;
} else if (conn.Type == "facebook") {
return "https://www.facebook.com/" + conn.ID;
} else if (conn.Type == "ebay") {
return "https://www.ebay.com/usr/" + conn.Name;
} else if (conn.Type == "instagram") {
return "https://www.instagram.com/" + conn.Name;
} else if (conn.Type == "tiktok") {
return "https://www.tiktok.com/@" + conn.Name;
}
return "";
}
ConnectionItem::ConnectionItem(const ConnectionData &conn) ConnectionItem::ConnectionItem(const ConnectionData &conn)
: m_box(Gtk::ORIENTATION_HORIZONTAL) : m_box(Gtk::ORIENTATION_HORIZONTAL)
, m_name(conn.Name) { , m_name(conn.Name) {
@ -8,23 +36,7 @@ ConnectionItem::ConnectionItem(const ConnectionData &conn)
try { try {
pixbuf = Gdk::Pixbuf::create_from_file(Abaddon::GetResPath("/" + conn.Type + ".png"), 32, 32); pixbuf = Gdk::Pixbuf::create_from_file(Abaddon::GetResPath("/" + conn.Type + ".png"), 32, 32);
} catch (const Glib::Exception &e) {} } catch (const Glib::Exception &e) {}
std::string url; std::string url = GetConnectionURL(conn);
if (conn.Type == "github")
url = "https://github.com/" + conn.Name;
else if (conn.Type == "steam")
url = "https://steamcommunity.com/profiles/" + conn.ID;
else if (conn.Type == "twitch")
url = "https://twitch.tv/" + conn.Name;
else if (conn.Type == "twitter")
url = "https://twitter.com/i/user/" + conn.ID;
else if (conn.Type == "spotify")
url = "https://open.spotify.com/user/" + conn.ID;
else if (conn.Type == "reddit")
url = "https://reddit.com/u/" + conn.Name;
else if (conn.Type == "youtube")
url = "https://www.youtube.com/channel/" + conn.ID;
else if (conn.Type == "facebook")
url = "https://www.facebook.com/" + conn.ID;
if (pixbuf) { if (pixbuf) {
m_image = Gtk::manage(new Gtk::Image(pixbuf)); m_image = Gtk::manage(new Gtk::Image(pixbuf));
m_image->get_style_context()->add_class("profile-connection-image"); m_image->get_style_context()->add_class("profile-connection-image");
@ -83,25 +95,33 @@ void ConnectionsContainer::SetConnections(const std::vector<ConnectionData> &con
static const std::unordered_set<std::string> supported_services = { static const std::unordered_set<std::string> supported_services = {
"battlenet", "battlenet",
"ebay",
"epicgames",
"facebook",
"github", "github",
"instagram",
"leagueoflegends", "leagueoflegends",
"paypal",
"playstation",
"reddit", "reddit",
"riotgames",
"skype", "skype",
"spotify", "spotify",
"steam", "steam",
"tiktok",
"twitch", "twitch",
"twitter", "twitter",
"xbox", "xbox",
"youtube", "youtube",
"facebook"
}; };
for (size_t i = 0; i < connections.size(); i++) { int i = 0;
const auto &conn = connections[i]; for (const auto &conn : connections) {
if (supported_services.find(conn.Type) == supported_services.end()) continue; if (supported_services.find(conn.Type) == supported_services.end()) continue;
auto widget = Gtk::manage(new ConnectionItem(conn)); auto widget = Gtk::manage(new ConnectionItem(conn));
widget->show(); widget->show();
attach(*widget, static_cast<int>(i % 2), static_cast<int>(i / 2), 1, 1); attach(*widget, i % 2, i / 2, 1, 1);
i++;
} }
set_halign(Gtk::ALIGN_FILL); set_halign(Gtk::ALIGN_FILL);

View File

@ -89,6 +89,7 @@ VoiceWindow::VoiceWindow(Snowflake channel_id)
, m_mute("Mute") , m_mute("Mute")
, m_deafen("Deafen") , m_deafen("Deafen")
, m_noise_suppression("Suppress Noise") , m_noise_suppression("Suppress Noise")
, m_mix_mono("Mix Mono")
, m_channel_id(channel_id) , m_channel_id(channel_id)
, m_menu_view("View") , m_menu_view("View")
, m_menu_view_settings("More _Settings", true) { , m_menu_view_settings("More _Settings", true) {
@ -178,6 +179,11 @@ VoiceWindow::VoiceWindow(Snowflake channel_id)
Abaddon::Get().GetAudio().SetSuppressNoise(m_noise_suppression.get_active()); Abaddon::Get().GetAudio().SetSuppressNoise(m_noise_suppression.get_active());
}); });
m_mix_mono.set_active(audio.GetMixMono());
m_mix_mono.signal_toggled().connect([this]() {
Abaddon::Get().GetAudio().SetMixMono(m_mix_mono.get_active());
});
auto *playback_renderer = Gtk::make_managed<Gtk::CellRendererText>(); auto *playback_renderer = Gtk::make_managed<Gtk::CellRendererText>();
m_playback_combo.set_valign(Gtk::ALIGN_END); m_playback_combo.set_valign(Gtk::ALIGN_END);
m_playback_combo.set_hexpand(true); m_playback_combo.set_hexpand(true);
@ -223,6 +229,7 @@ VoiceWindow::VoiceWindow(Snowflake channel_id)
m_controls.add(m_mute); m_controls.add(m_mute);
m_controls.add(m_deafen); m_controls.add(m_deafen);
m_controls.add(m_noise_suppression); m_controls.add(m_noise_suppression);
m_controls.add(m_mix_mono);
m_main.add(m_menu_bar); m_main.add(m_menu_bar);
m_main.add(m_controls); m_main.add(m_controls);
m_main.add(m_vad_value); m_main.add(m_vad_value);

View File

@ -54,6 +54,7 @@ private:
Gtk::Scale m_capture_gain; Gtk::Scale m_capture_gain;
Gtk::CheckButton m_noise_suppression; Gtk::CheckButton m_noise_suppression;
Gtk::CheckButton m_mix_mono;
Gtk::ComboBoxText m_vad_combo; Gtk::ComboBoxText m_vad_combo;
Gtk::ComboBox m_playback_combo; Gtk::ComboBox m_playback_combo;