#pragma once #include #include #include #include #include #include "discord/discord.hpp" #include "windows/mainwindow.hpp" #include "settings.hpp" #include "imgmanager.hpp" #include "emojis.hpp" #define APP_TITLE "Abaddon" class AudioManager; class Abaddon { private: Abaddon(); public: static Abaddon &Get(); Abaddon(const Abaddon &) = delete; Abaddon &operator=(const Abaddon &) = delete; Abaddon(Abaddon &&) = delete; Abaddon &operator=(Abaddon &&) = delete; int StartGTK(); void OnShutdown(); void StartDiscord(); void StopDiscord(); void LoadFromSettings(); void ActionConnect(); void ActionDisconnect(); void ActionSetToken(); void ActionJoinGuildDialog(); void ActionChannelOpened(Snowflake id, bool expand_to = true); void ActionChatInputSubmit(ChatSubmitParams data); void ActionChatLoadHistory(Snowflake id); void ActionChatEditMessage(Snowflake channel_id, Snowflake id); void ActionInsertMention(Snowflake id); void ActionLeaveGuild(Snowflake id); void ActionKickMember(Snowflake user_id, Snowflake guild_id); void ActionBanMember(Snowflake user_id, Snowflake guild_id); void ActionSetStatus(); void ActionReactionAdd(Snowflake id, const Glib::ustring ¶m); void ActionReactionRemove(Snowflake id, const Glib::ustring ¶m); void ActionGuildSettings(Snowflake id); void ActionAddRecipient(Snowflake channel_id); void ActionViewPins(Snowflake channel_id); void ActionViewThreads(Snowflake channel_id); #ifdef WITH_VOICE void ActionJoinVoiceChannel(Snowflake channel_id); void ActionDisconnectVoice(); #endif std::optional ShowTextPrompt(const Glib::ustring &prompt, const Glib::ustring &title, const Glib::ustring &placeholder = "", Gtk::Window *window = nullptr); bool ShowConfirm(const Glib::ustring &prompt, Gtk::Window *window = nullptr); void ActionReloadCSS(); ImageManager &GetImageManager(); EmojiResource &GetEmojis(); #ifdef WITH_VOICE AudioManager &GetAudio(); #endif std::string GetDiscordToken() const; bool IsDiscordActive() const; DiscordClient &GetDiscordClient(); const DiscordClient &GetDiscordClient() const; void DiscordOnReady(); void DiscordOnMessageCreate(const Message &message); void DiscordOnMessageDelete(Snowflake id, Snowflake channel_id); void DiscordOnMessageUpdate(Snowflake id, Snowflake channel_id); void DiscordOnGuildMemberListUpdate(Snowflake guild_id); void DiscordOnThreadMemberListUpdate(const ThreadMemberListUpdateData &data); void DiscordOnReactionAdd(Snowflake message_id, const Glib::ustring ¶m); void DiscordOnReactionRemove(Snowflake message_id, const Glib::ustring ¶m); void DiscordOnGuildJoinRequestCreate(const GuildJoinRequestCreateData &data); void DiscordOnMessageSent(const Message &data); void DiscordOnDisconnect(bool is_reconnecting, GatewayCloseCode close_code); void DiscordOnThreadUpdate(const ThreadUpdateData &data); #ifdef WITH_VOICE void OnVoiceConnected(); void OnVoiceDisconnected(); #endif SettingsManager::Settings &GetSettings(); Glib::RefPtr GetStyleProvider(); void ShowUserMenu(const GdkEvent *event, Snowflake id, Snowflake guild_id); void ManageHeapWindow(Gtk::Window *window); static std::string GetCSSPath(); static std::string GetResPath(); static std::string GetStateCachePath(); static std::string GetCSSPath(const std::string &path); static std::string GetResPath(const std::string &path); static std::string GetStateCachePath(const std::string &path); protected: void RunFirstTimeDiscordStartup(); void ShowGuildVerificationGateDialog(Snowflake guild_id); void CheckMessagesForMembers(const ChannelData &chan, const std::vector &msgs); void SetupUserMenu(); void SaveState(); void LoadState(); Snowflake m_shown_user_menu_id; Snowflake m_shown_user_menu_guild_id; Gtk::Menu *m_user_menu; Gtk::MenuItem *m_user_menu_info; Gtk::MenuItem *m_user_menu_insert_mention; Gtk::MenuItem *m_user_menu_ban; Gtk::MenuItem *m_user_menu_kick; Gtk::MenuItem *m_user_menu_copy_id; Gtk::MenuItem *m_user_menu_open_dm; Gtk::MenuItem *m_user_menu_roles; Gtk::MenuItem *m_user_menu_remove_recipient; Gtk::Menu *m_user_menu_roles_submenu; Gtk::Menu *m_tray_menu; Gtk::MenuItem *m_tray_exit; void on_user_menu_insert_mention(); void on_user_menu_ban(); void on_user_menu_kick(); void on_user_menu_copy_id(); void on_user_menu_open_dm(); void on_user_menu_remove_recipient(); void on_tray_click(); void on_tray_popup_menu(int button, int activate_time); void on_tray_menu_click(); void on_window_hide(); private: SettingsManager m_settings; DiscordClient m_discord; std::string m_discord_token; std::unordered_set m_channels_requested; std::unordered_set m_channels_history_loaded; std::unordered_set m_channels_history_loading; ImageManager m_img_mgr; EmojiResource m_emojis; #ifdef WITH_VOICE std::unique_ptr m_audio; Gtk::Window *m_voice_window = nullptr; #endif mutable std::mutex m_mutex; Glib::RefPtr m_gtk_app; Glib::RefPtr m_css_provider; Glib::RefPtr m_css_low_provider; // registered with a lower priority to allow better customization Glib::RefPtr m_tray; std::unique_ptr m_main_window; // wah wah cant create a gtkstylecontext fuck you };