From 530a385d4eb3d9ff4012551d69028ffe9aca838d Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 8 May 2017 12:08:24 +0300 Subject: [PATCH] Add sound override support by codes in Settings. --- Telegram/SourceFiles/auth_session.cpp | 31 +++++++++- Telegram/SourceFiles/auth_session.h | 8 +++ Telegram/SourceFiles/base/openssl_help.h | 14 ++--- Telegram/SourceFiles/calls/calls_call.cpp | 4 +- Telegram/SourceFiles/calls/calls_instance.cpp | 6 +- .../SourceFiles/settings/settings_widget.cpp | 61 +++++++++++++++---- .../window/notifications_manager.cpp | 2 +- 7 files changed, 100 insertions(+), 26 deletions(-) diff --git a/Telegram/SourceFiles/auth_session.cpp b/Telegram/SourceFiles/auth_session.cpp index 66372fbf44..a94081cece 100644 --- a/Telegram/SourceFiles/auth_session.cpp +++ b/Telegram/SourceFiles/auth_session.cpp @@ -24,6 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "messenger.h" #include "storage/file_download.h" #include "storage/localstorage.h" +#include "storage/serialize_common.h" #include "window/notifications_manager.h" #include "platform/platform_specific.h" #include "calls/calls_instance.h" @@ -35,7 +36,10 @@ constexpr auto kAutoLockTimeoutLateMs = TimeMs(3000); } // namespace QByteArray AuthSessionData::serialize() const { - auto size = sizeof(qint32) * 2; + auto size = sizeof(qint32) * 4; + for (auto i = _variables.soundOverrides.cbegin(), e = _variables.soundOverrides.cend(); i != e; ++i) { + size += Serialize::stringSize(i.key()) + Serialize::stringSize(i.value()); + } auto result = QByteArray(); result.reserve(size); @@ -50,6 +54,10 @@ QByteArray AuthSessionData::serialize() const { stream << static_cast(_variables.emojiPanelTab); stream << qint32(_variables.lastSeenWarningSeen ? 1 : 0); stream << qint32(_variables.tabbedSelectorSectionEnabled ? 1 : 0); + stream << qint32(_variables.soundOverrides.size()); + for (auto i = _variables.soundOverrides.cbegin(), e = _variables.soundOverrides.cend(); i != e; ++i) { + stream << i.key() << i.value(); + } } return result; } @@ -69,11 +77,23 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) { qint32 emojiPanTab = static_cast(EmojiPanelTab::Emoji); qint32 lastSeenWarningSeen = 0; qint32 tabbedSelectorSectionEnabled = 1; + QMap soundOverrides; stream >> emojiPanTab; stream >> lastSeenWarningSeen; if (!stream.atEnd()) { stream >> tabbedSelectorSectionEnabled; } + if (!stream.atEnd()) { + auto count = qint32(0); + stream >> count; + if (stream.status() == QDataStream::Ok) { + for (auto i = 0; i != count; ++i) { + QString key, value; + stream >> key >> value; + soundOverrides[key] = value; + } + } + } if (stream.status() != QDataStream::Ok) { LOG(("App Error: Bad data for AuthSessionData::constructFromSerialized()")); return; @@ -87,6 +107,15 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) { } _variables.lastSeenWarningSeen = (lastSeenWarningSeen == 1); _variables.tabbedSelectorSectionEnabled = (tabbedSelectorSectionEnabled == 1); + _variables.soundOverrides = std::move(soundOverrides); +} + +QString AuthSessionData::getSoundPath(const QString &key) const { + auto it = _variables.soundOverrides.constFind(key); + if (it != _variables.soundOverrides.end()) { + return it.value(); + } + return qsl(":/sounds/") + key + qsl(".mp3"); } AuthSession::AuthSession(UserId userId) diff --git a/Telegram/SourceFiles/auth_session.h b/Telegram/SourceFiles/auth_session.h index dda8b71640..220529845f 100644 --- a/Telegram/SourceFiles/auth_session.h +++ b/Telegram/SourceFiles/auth_session.h @@ -89,12 +89,20 @@ public: TimeMs lastTimeVideoPlayedAt() const { return _lastTimeVideoPlayedAt; } + void setSoundOverride(const QString &key, const QString &path) { + _variables.soundOverrides.insert(key, path); + } + void clearSoundOverrides() { + _variables.soundOverrides.clear(); + } + QString getSoundPath(const QString &key) const; private: struct Variables { bool lastSeenWarningSeen = false; EmojiPanelTab emojiPanelTab = EmojiPanelTab::Emoji; bool tabbedSelectorSectionEnabled = true; + QMap soundOverrides; }; base::Variable _contactsLoaded = { false }; diff --git a/Telegram/SourceFiles/base/openssl_help.h b/Telegram/SourceFiles/base/openssl_help.h index f86dbff507..3a2944ddf7 100644 --- a/Telegram/SourceFiles/base/openssl_help.h +++ b/Telegram/SourceFiles/base/openssl_help.h @@ -164,12 +164,12 @@ public: return failed() ? 0 : BN_num_bytes(raw()); } - std::vector getBytes() const { + base::byte_vector getBytes() const { if (failed()) { - return std::vector(); + return base::byte_vector(); } auto length = BN_num_bytes(raw()); - auto result = std::vector(length, gsl::byte()); + auto result = base::byte_vector(length, gsl::byte()); auto resultSize = BN_bn2bin(raw(), reinterpret_cast(result.data())); t_assert(resultSize == length); return result; @@ -204,14 +204,14 @@ inline BigNum operator-(const BigNum &a, const BigNum &b) { return result; } -inline std::array Sha256(base::const_byte_span bytes) { - auto result = std::array(); +inline base::byte_array Sha256(base::const_byte_span bytes) { + auto result = base::byte_array(); SHA256(reinterpret_cast(bytes.data()), bytes.size(), reinterpret_cast(result.data())); return result; } -inline std::array Sha1(base::const_byte_span bytes) { - auto result = std::array(); +inline base::byte_array Sha1(base::const_byte_span bytes) { + auto result = base::byte_array(); SHA1(reinterpret_cast(bytes.data()), bytes.size(), reinterpret_cast(result.data())); return result; } diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp index deb2ed2a49..ca2c88ca99 100644 --- a/Telegram/SourceFiles/calls/calls_call.cpp +++ b/Telegram/SourceFiles/calls/calls_call.cpp @@ -237,7 +237,7 @@ QString Call::getDebugLog() const { void Call::startWaitingTrack() { _waitingTrack = Media::Audio::Current().createTrack(); - auto trackFileName = (_type == Type::Outgoing) ? qsl(":/sounds/call_outgoing.mp3") : qsl(":/sounds/call_incoming.mp3"); + auto trackFileName = AuthSession::Current().data().getSoundPath((_type == Type::Outgoing) ? qsl("call_outgoing") : qsl("call_incoming")); _waitingTrack->samplePeakEach(kSoundSampleMs); _waitingTrack->fillFromFile(trackFileName); _waitingTrack->playInLoop(); @@ -255,7 +255,7 @@ bool Call::isKeyShaForFingerprintReady() const { return (_keyFingerprint != 0); } -std::array Call::getKeyShaForFingerprint() const { +base::byte_array Call::getKeyShaForFingerprint() const { Expects(isKeyShaForFingerprintReady()); Expects(!_ga.empty()); auto encryptedChatAuthKey = base::byte_vector(_authKey.size() + _ga.size(), gsl::byte {}); diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp index da4fc6f79f..fce7051eb0 100644 --- a/Telegram/SourceFiles/calls/calls_instance.cpp +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -73,7 +73,7 @@ void Instance::playSound(Sound sound) { case Sound::Busy: { if (!_callBusyTrack) { _callBusyTrack = Media::Audio::Current().createTrack(); - _callBusyTrack->fillFromFile(qsl(":/sounds/call_busy.mp3")); + _callBusyTrack->fillFromFile(AuthSession::Current().data().getSoundPath(qsl("call_busy"))); } _callBusyTrack->playOnce(); } break; @@ -81,7 +81,7 @@ void Instance::playSound(Sound sound) { case Sound::Ended: { if (!_callEndedTrack) { _callEndedTrack = Media::Audio::Current().createTrack(); - _callEndedTrack->fillFromFile(qsl(":/sounds/call_end.mp3")); + _callEndedTrack->fillFromFile(AuthSession::Current().data().getSoundPath(qsl("call_end"))); } _callEndedTrack->playOnce(); } break; @@ -89,7 +89,7 @@ void Instance::playSound(Sound sound) { case Sound::Connecting: { if (!_callConnectingTrack) { _callConnectingTrack = Media::Audio::Current().createTrack(); - _callConnectingTrack->fillFromFile(qsl(":/sounds/call_connect.mp3")); + _callConnectingTrack->fillFromFile(AuthSession::Current().data().getSoundPath(qsl("call_connect"))); } _callConnectingTrack->playOnce(); } break; diff --git a/Telegram/SourceFiles/settings/settings_widget.cpp b/Telegram/SourceFiles/settings/settings_widget.cpp index bacf0cd91b..e1318e31b9 100644 --- a/Telegram/SourceFiles/settings/settings_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_widget.cpp @@ -39,6 +39,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "core/file_utilities.h" #include "window/themes/window_theme.h" #include "window/themes/window_theme_editor.h" +#include "media/media_audio_track.h" namespace Settings { namespace { @@ -47,22 +48,22 @@ QString SecretText; QMap> Codes; void fillCodes() { - Codes.insert(qsl("debugmode"), []() { + Codes.insert(qsl("debugmode"), [] { QString text = cDebug() ? qsl("Do you want to disable DEBUG logs?") : qsl("Do you want to enable DEBUG logs?\n\nAll network events will be logged."); Ui::show(Box(text, [] { App::app()->onSwitchDebugMode(); })); }); - Codes.insert(qsl("testmode"), []() { + Codes.insert(qsl("testmode"), [] { auto text = cTestMode() ? qsl("Do you want to disable TEST mode?") : qsl("Do you want to enable TEST mode?\n\nYou will be switched to test cloud."); Ui::show(Box(text, [] { App::app()->onSwitchTestMode(); })); }); - Codes.insert(qsl("loadlang"), []() { + Codes.insert(qsl("loadlang"), [] { Global::RefChooseCustomLang().notify(); }); - Codes.insert(qsl("debugfiles"), []() { + Codes.insert(qsl("debugfiles"), [] { if (!cDebug()) return; if (DebugLogging::FileLoader()) { Global::RefDebugLoggingFlags() &= ~DebugLogging::FileLoaderFlag; @@ -71,16 +72,16 @@ void fillCodes() { } Ui::show(Box(DebugLogging::FileLoader() ? qsl("Enabled file download logging") : qsl("Disabled file download logging"))); }); - Codes.insert(qsl("crashplease"), []() { + Codes.insert(qsl("crashplease"), [] { Unexpected("Crashed in Settings!"); }); - Codes.insert(qsl("workmode"), []() { + Codes.insert(qsl("workmode"), [] { auto text = Global::DialogsModeEnabled() ? qsl("Disable work mode?") : qsl("Enable work mode?"); Ui::show(Box(text, [] { App::app()->onSwitchWorkMode(); })); }); - Codes.insert(qsl("moderate"), []() { + Codes.insert(qsl("moderate"), [] { auto text = Global::ModerateModeEnabled() ? qsl("Disable moderate mode?") : qsl("Enable moderate mode?"); Ui::show(Box(text, []() { Global::SetModerateModeEnabled(!Global::ModerateModeEnabled()); @@ -88,22 +89,22 @@ void fillCodes() { Ui::hideLayer(); })); }); - Codes.insert(qsl("getdifference"), []() { + Codes.insert(qsl("getdifference"), [] { if (auto main = App::main()) { main->getDifference(); } }); - Codes.insert(qsl("loadcolors"), []() { + Codes.insert(qsl("loadcolors"), [] { FileDialog::GetOpenPath("Open palette file", "Palette (*.tdesktop-palette)", [](const FileDialog::OpenResult &result) { if (!result.paths.isEmpty()) { Window::Theme::Apply(result.paths.front()); } }); }); - Codes.insert(qsl("edittheme"), []() { + Codes.insert(qsl("edittheme"), [] { Window::Theme::Editor::Start(); }); - Codes.insert(qsl("videoplayer"), []() { + Codes.insert(qsl("videoplayer"), [] { auto text = cUseExternalVideoPlayer() ? qsl("Use internal video player?") : qsl("Use external video player?"); Ui::show(Box(text, [] { cSetUseExternalVideoPlayer(!cUseExternalVideoPlayer()); @@ -111,7 +112,7 @@ void fillCodes() { Ui::hideLayer(); })); }); - Codes.insert(qsl("endpoints"), []() { + Codes.insert(qsl("endpoints"), [] { FileDialog::GetOpenPath("Open DC endpoints", "DC Endpoints (*.tdesktop-endpoints)", [](const FileDialog::OpenResult &result) { if (!result.paths.isEmpty()) { if (!Messenger::Instance().mtp()->dcOptions()->loadFromFile(result.paths.front())) { @@ -120,6 +121,42 @@ void fillCodes() { } }); }); + auto audioFilters = qsl("Audio files (*.wav *.mp3);;") + FileDialog::AllFilesFilter(); + auto audioKeys = { + qsl("msg_incoming"), + qsl("call_incoming"), + qsl("call_outgoing"), + qsl("call_busy"), + qsl("call_connect"), + qsl("call_end"), + }; + for (auto &key : audioKeys) { + Codes.insert(key, [audioFilters, key] { + if (!AuthSession::Exists()) { + return; + } + + FileDialog::GetOpenPath("Open audio file", audioFilters, [key](const FileDialog::OpenResult &result) { + if (AuthSession::Exists() && !result.paths.isEmpty()) { + auto track = Media::Audio::Current().createTrack(); + track->fillFromFile(result.paths.front()); + if (track->failed()) { + Ui::show(Box("Could not audio :( Errors in 'log.txt'.")); + } else { + AuthSession::Current().data().setSoundOverride(key, result.paths.front()); + Local::writeUserSettings(); + } + } + }); + }); + } + Codes.insert(qsl("sounds_reset"), [] { + if (AuthSession::Exists()) { + AuthSession::Current().data().clearSoundOverrides(); + Local::writeUserSettings(); + Ui::show(Box("All sound overrides were reset.")); + } + }); } void codesFeedString(const QString &text) { diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index 288ecfbeb9..c874917dce 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -362,7 +362,7 @@ void System::ensureSoundCreated() { } _soundTrack = Media::Audio::Current().createTrack(); - _soundTrack->fillFromFile(qsl(":/sounds/msg_incoming.mp3")); + _soundTrack->fillFromFile(AuthSession::Current().data().getSoundPath(qsl("msg_incoming"))); } void System::updateAll() {