Skip to content

Commit

Permalink
Merge branch 'master' into rnnoise
Browse files Browse the repository at this point in the history
  • Loading branch information
ouwou committed Jul 18, 2023
2 parents 0f38145 + 857e94a commit d04e101
Show file tree
Hide file tree
Showing 67 changed files with 1,472 additions and 378 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
with:
cond: ${{ matrix.mindeps == true }}
if_true: |
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.buildtype }} -DUSE_LIBHANDY=OFF -DENABLE_VOICE=OFF -DENABLE_NOTIFICATION_SOUNDS=OFF
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.buildtype }} -DUSE_LIBHANDY=OFF -DENABLE_VOICE=OFF -DENABLE_NOTIFICATION_SOUNDS=OFF -DENABLE_QRCODE_LOGIN=OFF
cmake --build build
if_false: |
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.buildtype }} -DCMAKE_CXX_FLAGS="-Wl,--default-image-base-low"
Expand Down Expand Up @@ -95,7 +95,6 @@ jobs:
mkdir -p 16x16/devices 24x24/devices 32x32/devices 48x48/devices 64x64/devices 96x96/devices scalable/devices
mkdir -p 16x16/status 24x24/status 32x32/status 48x48/status 64x64/status 96x96/status scalable/status
cd ${GITHUB_WORKSPACE}
cp ci/gtk-for-windows/gtk-nsis-pack/share/icons/Adwaita/icon-theme.cache ${artifact_dir}/share/icons/Adwaita/icon-theme.cache
cp ci/gtk-for-windows/gtk-nsis-pack/share/icons/Adwaita/index.theme ${artifact_dir}/share/icons/Adwaita/index.theme
cat "ci/used-icons.txt" | sed 's/\r$//' | xargs -I % cp ci/gtk-for-windows/gtk-nsis-pack/share/icons/Adwaita/16x16/%.symbolic.png ${artifact_dir}/share/icons/Adwaita/16x16/%.symbolic.png || :
cat "ci/used-icons.txt" | sed 's/\r$//' | xargs -I % cp ci/gtk-for-windows/gtk-nsis-pack/share/icons/Adwaita/24x24/%.symbolic.png ${artifact_dir}/share/icons/Adwaita/24x24/%.symbolic.png || :
Expand All @@ -104,6 +103,8 @@ jobs:
cat "ci/used-icons.txt" | sed 's/\r$//' | xargs -I % cp ci/gtk-for-windows/gtk-nsis-pack/share/icons/Adwaita/64x64/%.symbolic.png ${artifact_dir}/share/icons/Adwaita/64x64/%.symbolic.png || :
cat "ci/used-icons.txt" | sed 's/\r$//' | xargs -I % cp ci/gtk-for-windows/gtk-nsis-pack/share/icons/Adwaita/96x96/%.symbolic.png ${artifact_dir}/share/icons/Adwaita/96x96/%.symbolic.png || :
cat "ci/used-icons.txt" | sed 's/\r$//' | xargs -I % cp ci/gtk-for-windows/gtk-nsis-pack/share/icons/Adwaita/scalable/%.svg ${artifact_dir}/share/icons/Adwaita/scalable/%.svg || :
cd ${artifact_dir}/share/icons/Adwaita
gtk-update-icon-cache .
- name: Upload build (1)
uses: haya14busa/action-cond@v1
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
[submodule "subprojects/rnnoise"]
path = subprojects/rnnoise
url = https://github.com/xiph/rnnoise
[submodule "subprojects/qrcodegen"]
path = subprojects/qrcodegen
url = https://github.com/nayuki/QR-Code-generator
23 changes: 22 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ option(ENABLE_VOICE "Enable voice suppport" ON)
option(USE_KEYCHAIN "Store the token in the keychain (default)" ON)
option(ENABLE_NOTIFICATION_SOUNDS "Enable notification sounds (default)" ON)
option(ENABLE_RNNOISE "Enable RNNoise for voice activity detection (default)" ON)
option(ENABLE_QRCODE_LOGIN "Enable QR code login (default)" ON)

find_package(nlohmann_json REQUIRED)
find_package(CURL)
Expand Down Expand Up @@ -62,6 +63,15 @@ target_include_directories(abaddon PUBLIC ${ZLIB_INCLUDE_DIRS})
target_include_directories(abaddon PUBLIC ${SQLite3_INCLUDE_DIRS})
target_include_directories(abaddon PUBLIC ${NLOHMANN_JSON_INCLUDE_DIRS})

if (ENABLE_QRCODE_LOGIN)
add_library(qrcodegen subprojects/qrcodegen/cpp/qrcodegen.hpp subprojects/qrcodegen/cpp/qrcodegen.cpp)
target_include_directories(qrcodegen PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/subprojects/qrcodegen/cpp")
target_link_libraries(abaddon qrcodegen)

target_include_directories(abaddon PUBLIC "subprojects/qrcodegen/cpp")
target_compile_definitions(abaddon PRIVATE WITH_QRLOGIN)
endif ()

target_precompile_headers(abaddon PRIVATE <gtkmm.h> src/abaddon.hpp src/util.hpp)

if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
Expand Down Expand Up @@ -180,6 +190,12 @@ if (ENABLE_VOICE)
target_link_libraries(abaddon rnnoise)
endif ()
endif ()

if (APPLE)
target_link_libraries(abaddon "-framework CoreFoundation")
target_link_libraries(abaddon "-framework CoreAudio")
target_link_libraries(abaddon "-framework AudioToolbox")
endif ()
endif ()

if (${ENABLE_NOTIFICATION_SOUNDS})
Expand All @@ -188,6 +204,11 @@ if (${ENABLE_NOTIFICATION_SOUNDS})
endif ()

if (USE_MINIAUDIO)
target_include_directories(abaddon PUBLIC subprojects/miniaudio)
find_path(MINIAUDIO_INCLUDE_DIR
NAMES miniaudio.h
HINTS subprojects
PATH_SUFFIXES miniaudio
REQUIRED)
target_include_directories(abaddon PUBLIC ${MINIAUDIO_INCLUDE_DIR})
target_compile_definitions(abaddon PRIVATE WITH_MINIAUDIO)
endif ()
53 changes: 27 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,32 +226,33 @@ Used in guild settings popup:

Used in profile popup:

| Selector | Description |
|------------------------------|---------------------------------------------------------|
| `.mutual-friend-item` | Applied to every item in the mutual friends list |
| `.mutual-friend-item-name` | Name in mutual friend item |
| `.mutual-friend-item-avatar` | Avatar in mutual friend item |
| `.mutual-guild-item` | Applied to every item in the mutual guilds list |
| `.mutual-guild-item-name` | Name in mutual guild item |
| `.mutual-guild-item-icon` | Icon in mutual guild item |
| `.mutual-guild-item-nick` | User nickname in mutual guild item |
| `.profile-connection` | Applied to every item in the user connections list |
| `.profile-connection-label` | Label in profile connection item |
| `.profile-connection-check` | Checkmark in verified profile connection items |
| `.profile-connections` | Container for profile connections |
| `.profile-notes` | Container for notes in profile window |
| `.profile-notes-label` | Label that says "NOTE" |
| `.profile-notes-text` | Actual note text |
| `.profile-info-pane` | Applied to container for info section of profile popup |
| `.profile-info-created` | Label for creation date of profile |
| `.user-profile-window` | |
| `.profile-main-container` | Inner container for profile |
| `.profile-avatar` | |
| `.profile-username` | |
| `.profile-switcher` | Buttons used to switch viewed section of profile |
| `.profile-stack` | Container for profile info that can be switched between |
| `.profile-badges` | Container for badges |
| `.profile-badge` | |
| Selector | Description |
|--------------------------------|------------------------------------------------------------|
| `.mutual-friend-item` | Applied to every item in the mutual friends list |
| `.mutual-friend-item-name` | Name in mutual friend item |
| `.mutual-friend-item-avatar` | Avatar in mutual friend item |
| `.mutual-guild-item` | Applied to every item in the mutual guilds list |
| `.mutual-guild-item-name` | Name in mutual guild item |
| `.mutual-guild-item-icon` | Icon in mutual guild item |
| `.mutual-guild-item-nick` | User nickname in mutual guild item |
| `.profile-connection` | Applied to every item in the user connections list |
| `.profile-connection-label` | Label in profile connection item |
| `.profile-connection-check` | Checkmark in verified profile connection items |
| `.profile-connections` | Container for profile connections |
| `.profile-notes` | Container for notes in profile window |
| `.profile-notes-label` | Label that says "NOTE" |
| `.profile-notes-text` | Actual note text |
| `.profile-info-pane` | Applied to container for info section of profile popup |
| `.profile-info-created` | Label for creation date of profile |
| `.user-profile-window` | |
| `.profile-main-container` | Inner container for profile |
| `.profile-avatar` | |
| `.profile-username` | User's display name (username for backwards compatibility) |
| `.profile-username-nondisplay` | User's actual username |
| `.profile-switcher` | Buttons used to switch viewed section of profile |
| `.profile-stack` | Container for profile info that can be switched between |
| `.profile-badges` | Container for badges |
| `.profile-badge` | |

### Settings

Expand Down
13 changes: 13 additions & 0 deletions res/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@
border: 1px solid #026FB9;
}

.message-input.editing {
border: 1px solid #b9026f;
}

.message-input.bad-input {
border: 1px solid #dd3300;
}
Expand Down Expand Up @@ -237,6 +241,10 @@
font-size: 20px;
}

.profile-username-nondisplay {
margin-left: 10px;
}

.profile-badge {
margin-right: 10px;
}
Expand Down Expand Up @@ -382,3 +390,8 @@
.voice-state-server {
color: red;
}

spinbutton {
color: @text_color;
margin-top: 10px;
}
54 changes: 40 additions & 14 deletions src/abaddon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "audio/manager.hpp"
#include "discord/discord.hpp"
#include "dialogs/token.hpp"
#include "dialogs/editmessage.hpp"
#include "dialogs/confirm.hpp"
#include "dialogs/setstatus.hpp"
#include "dialogs/friendpicker.hpp"
Expand All @@ -21,6 +20,7 @@
#include "windows/voicewindow.hpp"
#include "startup.hpp"
#include "notifications/notifications.hpp"
#include "remoteauth/remoteauthdialog.hpp"

#ifdef WITH_LIBHANDY
#include <handy.h>
Expand Down Expand Up @@ -252,6 +252,12 @@ int Abaddon::StartGTK() {
}
#endif

#ifdef _WIN32
if (m_settings.GetSettings().HideConsole) {
ShowWindow(GetConsoleWindow(), SW_HIDE);
}
#endif

// store must be checked before this can be called
m_main_window->UpdateComponents();

Expand All @@ -261,6 +267,7 @@ int Abaddon::StartGTK() {
m_main_window->signal_action_connect().connect(sigc::mem_fun(*this, &Abaddon::ActionConnect));
m_main_window->signal_action_disconnect().connect(sigc::mem_fun(*this, &Abaddon::ActionDisconnect));
m_main_window->signal_action_set_token().connect(sigc::mem_fun(*this, &Abaddon::ActionSetToken));
m_main_window->signal_action_login_qr().connect(sigc::mem_fun(*this, &Abaddon::ActionLoginQR));
m_main_window->signal_action_reload_css().connect(sigc::mem_fun(*this, &Abaddon::ActionReloadCSS));
m_main_window->signal_action_set_status().connect(sigc::mem_fun(*this, &Abaddon::ActionSetStatus));
m_main_window->signal_action_add_recipient().connect(sigc::mem_fun(*this, &Abaddon::ActionAddRecipient));
Expand Down Expand Up @@ -828,6 +835,21 @@ void Abaddon::ActionSetToken() {
m_main_window->UpdateMenus();
}

void Abaddon::ActionLoginQR() {
#ifdef WITH_QRLOGIN
RemoteAuthDialog dlg(*m_main_window);
auto response = dlg.run();
if (response == Gtk::RESPONSE_OK) {
m_discord_token = dlg.GetToken();
m_discord.UpdateToken(m_discord_token);
m_main_window->UpdateComponents();
GetSettings().DiscordToken = m_discord_token;
ActionConnect();
}
m_main_window->UpdateMenus();
#endif
}

void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) {
if (!id.IsValid()) {
m_discord.SetReferringChannel(Snowflake::Invalid);
Expand Down Expand Up @@ -914,24 +936,26 @@ void Abaddon::ActionChatLoadHistory(Snowflake id) {
}

void Abaddon::ActionChatInputSubmit(ChatSubmitParams data) {
if (data.Message.substr(0, 7) == "/shrug " || data.Message == "/shrug")
if (data.Message.substr(0, 7) == "/shrug " || data.Message == "/shrug") {
data.Message = data.Message.substr(6) + "\xC2\xAF\x5C\x5F\x28\xE3\x83\x84\x29\x5F\x2F\xC2\xAF"; // this is important
}

if (data.Message.substr(0, 8) == "@silent " || (data.Message.substr(0, 7) == "@silent" && !data.Attachments.empty())) {
data.Silent = true;
data.Message = data.Message.substr(7);
}

if (!m_discord.HasChannelPermission(m_discord.GetUserData().ID, data.ChannelID, Permission::VIEW_CHANNEL)) return;

m_discord.SendChatMessage(data, NOOP_CALLBACK);
if (data.EditingID.IsValid()) {
m_discord.EditMessage(data.ChannelID, data.EditingID, data.Message);
} else {
m_discord.SendChatMessage(data, NOOP_CALLBACK);
}
}

void Abaddon::ActionChatEditMessage(Snowflake channel_id, Snowflake id) {
const auto msg = m_discord.GetMessage(id);
if (!msg.has_value()) return;
EditMessageDialog dlg(*m_main_window);
dlg.SetContent(msg->Content);
auto response = dlg.run();
if (response == Gtk::RESPONSE_OK) {
auto new_content = dlg.GetContent();
m_discord.EditMessage(channel_id, id, new_content);
}
m_main_window->EditMessage(id);
}

void Abaddon::ActionInsertMention(Snowflake id) {
Expand All @@ -952,7 +976,7 @@ void Abaddon::ActionKickMember(Snowflake user_id, Snowflake guild_id) {
ConfirmDialog dlg(*m_main_window);
const auto user = m_discord.GetUser(user_id);
if (user.has_value())
dlg.SetConfirmText("Are you sure you want to kick " + user->Username + "#" + user->Discriminator + "?");
dlg.SetConfirmText("Are you sure you want to kick " + user->GetUsername() + "?");
auto response = dlg.run();
if (response == Gtk::RESPONSE_OK)
m_discord.KickUser(user_id, guild_id);
Expand All @@ -962,7 +986,7 @@ void Abaddon::ActionBanMember(Snowflake user_id, Snowflake guild_id) {
ConfirmDialog dlg(*m_main_window);
const auto user = m_discord.GetUser(user_id);
if (user.has_value())
dlg.SetConfirmText("Are you sure you want to ban " + user->Username + "#" + user->Discriminator + "?");
dlg.SetConfirmText("Are you sure you want to ban " + user->GetUsername() + "?");
auto response = dlg.run();
if (response == Gtk::RESPONSE_OK)
m_discord.BanUser(user_id, guild_id);
Expand Down Expand Up @@ -1127,9 +1151,11 @@ int main(int argc, char **argv) {
#endif

spdlog::cfg::load_env_levels();
auto log_ui = spdlog::stdout_color_mt("ui");
auto log_audio = spdlog::stdout_color_mt("audio");
auto log_voice = spdlog::stdout_color_mt("voice");
auto log_discord = spdlog::stdout_color_mt("discord");
auto log_ra = spdlog::stdout_color_mt("remote-auth");

Gtk::Main::init_gtkmm_internals(); // why???
return Abaddon::Get().StartGTK();
Expand Down
1 change: 1 addition & 0 deletions src/abaddon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Abaddon {
void ActionConnect();
void ActionDisconnect();
void ActionSetToken();
void ActionLoginQR();
void ActionJoinGuildDialog();
void ActionChannelOpened(Snowflake id, bool expand_to = true);
void ActionChatInputSubmit(ChatSubmitParams data);
Expand Down
3 changes: 3 additions & 0 deletions src/audio/ma_impl.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#ifdef WITH_MINIAUDIO
#define MINIAUDIO_IMPLEMENTATION
#ifdef __APPLE__
#define MA_NO_RUNTIME_LINKING
#endif
#include <miniaudio.h>
#endif
48 changes: 24 additions & 24 deletions src/audio/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,23 @@ AudioManager::AudioManager() {
if (const auto playback_id = m_devices.GetDefaultPlayback(); playback_id.has_value()) {
m_playback_id = *playback_id;
m_playback_config.playback.pDeviceID = &m_playback_id;
}

if (ma_device_init(&m_context, &m_playback_config, &m_playback_device) != MA_SUCCESS) {
spdlog::get("audio")->error("failed to initialize playback device");
m_ok = false;
return;
}
if (ma_device_init(&m_context, &m_playback_config, &m_playback_device) != MA_SUCCESS) {
spdlog::get("audio")->error("failed to initialize playback device");
m_ok = false;
return;
}

if (ma_device_start(&m_playback_device) != MA_SUCCESS) {
spdlog::get("audio")->error("failed to start playback");
ma_device_uninit(&m_playback_device);
m_ok = false;
return;
if (ma_device_start(&m_playback_device) != MA_SUCCESS) {
spdlog::get("audio")->error("failed to start playback");
ma_device_uninit(&m_playback_device);
m_ok = false;
return;
}

char playback_device_name[MA_MAX_DEVICE_NAME_LENGTH + 1];
ma_device_get_name(&m_playback_device, ma_device_type_playback, playback_device_name, sizeof(playback_device_name), nullptr);
spdlog::get("audio")->info("using {} as playback device", playback_device_name);
}

m_capture_config = ma_device_config_init(ma_device_type_capture);
Expand All @@ -122,21 +126,17 @@ AudioManager::AudioManager() {
if (const auto capture_id = m_devices.GetDefaultCapture(); capture_id.has_value()) {
m_capture_id = *capture_id;
m_capture_config.capture.pDeviceID = &m_capture_id;
}

if (ma_device_init(&m_context, &m_capture_config, &m_capture_device) != MA_SUCCESS) {
spdlog::get("audio")->error("failed to initialize capture device");
m_ok = false;
return;
}

char playback_device_name[MA_MAX_DEVICE_NAME_LENGTH + 1];
ma_device_get_name(&m_playback_device, ma_device_type_playback, playback_device_name, sizeof(playback_device_name), nullptr);
spdlog::get("audio")->info("using {} as playback device", playback_device_name);
if (ma_device_init(&m_context, &m_capture_config, &m_capture_device) != MA_SUCCESS) {
spdlog::get("audio")->error("failed to initialize capture device");
m_ok = false;
return;
}

char capture_device_name[MA_MAX_DEVICE_NAME_LENGTH + 1];
ma_device_get_name(&m_capture_device, ma_device_type_capture, capture_device_name, sizeof(capture_device_name), nullptr);
spdlog::get("audio")->info("using {} as capture device", capture_device_name);
char capture_device_name[MA_MAX_DEVICE_NAME_LENGTH + 1];
ma_device_get_name(&m_capture_device, ma_device_type_capture, capture_device_name, sizeof(capture_device_name), nullptr);
spdlog::get("audio")->info("using {} as capture device", capture_device_name);
}

Glib::signal_timeout().connect(sigc::mem_fun(*this, &AudioManager::DecayVolumeMeters), 40);
}
Expand Down
Loading

0 comments on commit d04e101

Please sign in to comment.