diff --git a/Telegram/Resources/qrc/telegram/sounds.qrc b/Telegram/Resources/qrc/telegram/sounds.qrc
index 6135e0050..69d1427e5 100644
--- a/Telegram/Resources/qrc/telegram/sounds.qrc
+++ b/Telegram/Resources/qrc/telegram/sounds.qrc
@@ -6,5 +6,8 @@
../../sounds/call_end.mp3
../../sounds/call_incoming.mp3
../../sounds/call_outgoing.mp3
+ ../../sounds/group_call_start.mp3
+ ../../sounds/group_call_connect.mp3
+ ../../sounds/group_call_end.mp3
diff --git a/Telegram/Resources/sounds/group_call_connect.mp3 b/Telegram/Resources/sounds/group_call_connect.mp3
new file mode 100644
index 000000000..4e0f60b4f
Binary files /dev/null and b/Telegram/Resources/sounds/group_call_connect.mp3 differ
diff --git a/Telegram/Resources/sounds/group_call_end.mp3 b/Telegram/Resources/sounds/group_call_end.mp3
new file mode 100644
index 000000000..c03390958
Binary files /dev/null and b/Telegram/Resources/sounds/group_call_end.mp3 differ
diff --git a/Telegram/Resources/sounds/group_call_start.mp3 b/Telegram/Resources/sounds/group_call_start.mp3
new file mode 100644
index 000000000..527959c9d
Binary files /dev/null and b/Telegram/Resources/sounds/group_call_start.mp3 differ
diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp
index 669d9153c..e78dbd8e9 100644
--- a/Telegram/SourceFiles/calls/calls_call.cpp
+++ b/Telegram/SourceFiles/calls/calls_call.cpp
@@ -951,20 +951,20 @@ void Call::setState(State state) {
_startTime = crl::now();
break;
case State::ExchangingKeys:
- _delegate->playSound(Delegate::Sound::Connecting);
+ _delegate->callPlaySound(Delegate::CallSound::Connecting);
break;
case State::Ended:
- _delegate->playSound(Delegate::Sound::Ended);
+ _delegate->callPlaySound(Delegate::CallSound::Ended);
[[fallthrough]];
case State::EndedByOtherDevice:
_delegate->callFinished(this);
break;
case State::Failed:
- _delegate->playSound(Delegate::Sound::Ended);
+ _delegate->callPlaySound(Delegate::CallSound::Ended);
_delegate->callFailed(this);
break;
case State::Busy:
- _delegate->playSound(Delegate::Sound::Busy);
+ _delegate->callPlaySound(Delegate::CallSound::Busy);
break;
}
}
diff --git a/Telegram/SourceFiles/calls/calls_call.h b/Telegram/SourceFiles/calls/calls_call.h
index 531397c1d..e4dcf2d65 100644
--- a/Telegram/SourceFiles/calls/calls_call.h
+++ b/Telegram/SourceFiles/calls/calls_call.h
@@ -62,15 +62,16 @@ public:
virtual void callFailed(not_null call) = 0;
virtual void callRedial(not_null call) = 0;
- enum class Sound {
+ enum class CallSound {
Connecting,
Busy,
Ended,
};
- virtual void playSound(Sound sound) = 0;
+ virtual void callPlaySound(CallSound sound) = 0;
virtual void callRequestPermissionsOrFail(
Fn onSuccess,
bool video) = 0;
+
virtual auto getVideoCapture()
-> std::shared_ptr = 0;
diff --git a/Telegram/SourceFiles/calls/calls_group_call.cpp b/Telegram/SourceFiles/calls/calls_group_call.cpp
index 5ee162687..e705c4377 100644
--- a/Telegram/SourceFiles/calls/calls_group_call.cpp
+++ b/Telegram/SourceFiles/calls/calls_group_call.cpp
@@ -42,6 +42,7 @@ constexpr auto kMaxInvitePerSlice = 10;
constexpr auto kCheckLastSpokeInterval = crl::time(1000);
constexpr auto kCheckJoinedTimeout = 4 * crl::time(1000);
constexpr auto kUpdateSendActionEach = crl::time(500);
+constexpr auto kPlayConnectingEach = crl::time(1056) + 2 * crl::time(1000);
} // namespace
@@ -55,7 +56,8 @@ GroupCall::GroupCall(
, _api(&peer->session().mtp())
, _lastSpokeCheckTimer([=] { checkLastSpoke(); })
, _checkJoinedTimer([=] { checkJoined(); })
-, _pushToTalkCancelTimer([=] { pushToTalkCancel(); }) {
+, _pushToTalkCancelTimer([=] { pushToTalkCancel(); })
+, _connectingSoundTimer([=] { playConnectingSoundOnce(); }) {
_muted.value(
) | rpl::combine_previous(
) | rpl::start_with_next([=](MuteState previous, MuteState state) {
@@ -109,14 +111,22 @@ void GroupCall::setState(State state) {
}
_state = state;
- if (_state.current() == State::Joined) {
- if (!_pushToTalkStarted) {
- _pushToTalkStarted = true;
+ if (state == State::Joined) {
+ stopConnectingSound();
+ if (!_hadJoinedState) {
+ _hadJoinedState = true;
applyGlobalShortcutChanges();
+ _delegate->groupCallPlaySound(Delegate::GroupCallSound::Started);
}
if (const auto call = _peer->groupCall(); call && call->id() == _id) {
call->setInCall();
}
+ } else if (state == State::Connecting || state == State::Joining) {
+ if (_hadJoinedState) {
+ playConnectingSound();
+ }
+ } else {
+ stopConnectingSound();
}
if (false
@@ -127,6 +137,10 @@ void GroupCall::setState(State state) {
destroyController();
}
switch (state) {
+ case State::HangingUp:
+ case State::FailedHangingUp:
+ _delegate->groupCallPlaySound(Delegate::GroupCallSound::Ended);
+ break;
case State::Ended:
_delegate->groupCallFinished(this);
break;
@@ -141,6 +155,22 @@ void GroupCall::setState(State state) {
}
}
+void GroupCall::playConnectingSound() {
+ if (_connectingSoundTimer.isActive()) {
+ return;
+ }
+ playConnectingSoundOnce();
+ _connectingSoundTimer.callEach(kPlayConnectingEach);
+}
+
+void GroupCall::stopConnectingSound() {
+ _connectingSoundTimer.cancel();
+}
+
+void GroupCall::playConnectingSoundOnce() {
+ _delegate->groupCallPlaySound(Delegate::GroupCallSound::Connecting);
+}
+
void GroupCall::start() {
_createRequestId = _api.request(MTPphone_CreateGroupCall(
_peer->input,
diff --git a/Telegram/SourceFiles/calls/calls_group_call.h b/Telegram/SourceFiles/calls/calls_group_call.h
index 0ad338c41..8af623cee 100644
--- a/Telegram/SourceFiles/calls/calls_group_call.h
+++ b/Telegram/SourceFiles/calls/calls_group_call.h
@@ -61,6 +61,13 @@ public:
virtual void groupCallFailed(not_null call) = 0;
virtual void groupCallRequestPermissionsOrFail(
Fn onSuccess) = 0;
+
+ enum class GroupCallSound {
+ Started,
+ Connecting,
+ Ended,
+ };
+ virtual void groupCallPlaySound(GroupCallSound sound) = 0;
};
using GlobalShortcutManager = base::GlobalShortcutManager;
@@ -162,6 +169,10 @@ private:
void checkGlobalShortcutAvailability();
void checkJoined();
+ void playConnectingSound();
+ void stopConnectingSound();
+ void playConnectingSoundOnce();
+
[[nodiscard]] MTPInputGroupCall inputCall() const;
const not_null _delegate;
@@ -191,7 +202,8 @@ private:
std::shared_ptr _shortcutManager;
std::shared_ptr _pushToTalk;
base::Timer _pushToTalkCancelTimer;
- bool _pushToTalkStarted = false;
+ base::Timer _connectingSoundTimer;
+ bool _hadJoinedState = false;
rpl::lifetime _lifetime;
diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp
index 93ffbb202..7ce5ede23 100644
--- a/Telegram/SourceFiles/calls/calls_instance.cpp
+++ b/Telegram/SourceFiles/calls/calls_instance.cpp
@@ -98,35 +98,45 @@ void Instance::groupCallFailed(not_null call) {
});
}
-void Instance::playSound(Sound sound) {
- switch (sound) {
- case Sound::Busy: {
- if (!_callBusyTrack) {
- _callBusyTrack = Media::Audio::Current().createTrack();
- _callBusyTrack->fillFromFile(
- Core::App().settings().getSoundPath(qsl("call_busy")));
- }
- _callBusyTrack->playOnce();
- } break;
-
- case Sound::Ended: {
- if (!_callEndedTrack) {
- _callEndedTrack = Media::Audio::Current().createTrack();
- _callEndedTrack->fillFromFile(
- Core::App().settings().getSoundPath(qsl("call_end")));
- }
- _callEndedTrack->playOnce();
- } break;
-
- case Sound::Connecting: {
- if (!_callConnectingTrack) {
- _callConnectingTrack = Media::Audio::Current().createTrack();
- _callConnectingTrack->fillFromFile(
- Core::App().settings().getSoundPath(qsl("call_connect")));
- }
- _callConnectingTrack->playOnce();
- } break;
+not_null Instance::ensureSoundLoaded(
+ const QString &key) {
+ const auto i = _tracks.find(key);
+ if (i != end(_tracks)) {
+ return i->second.get();
}
+ const auto result = _tracks.emplace(
+ key,
+ Media::Audio::Current().createTrack()).first->second.get();
+ result->fillFromFile(Core::App().settings().getSoundPath(key));
+ return result;
+}
+
+void Instance::playSoundOnce(const QString &key) {
+ ensureSoundLoaded(key)->playOnce();
+}
+
+void Instance::callPlaySound(CallSound sound) {
+ playSoundOnce([&] {
+ switch (sound) {
+ case CallSound::Busy: return "call_busy";
+ case CallSound::Ended: return "call_end";
+ case CallSound::Connecting: return "call_connect";
+ }
+ Unexpected("CallSound in Instance::callPlaySound.");
+ return "";
+ }());
+}
+
+void Instance::groupCallPlaySound(GroupCallSound sound) {
+ playSoundOnce([&] {
+ switch (sound) {
+ case GroupCallSound::Started: return "group_call_start";
+ case GroupCallSound::Ended: return "group_call_end";
+ case GroupCallSound::Connecting: return "group_call_connect";
+ }
+ Unexpected("GroupCallSound in Instance::groupCallPlaySound.");
+ return "";
+ }());
}
void Instance::destroyCall(not_null call) {
diff --git a/Telegram/SourceFiles/calls/calls_instance.h b/Telegram/SourceFiles/calls/calls_instance.h
index 0e2820800..73844d24f 100644
--- a/Telegram/SourceFiles/calls/calls_instance.h
+++ b/Telegram/SourceFiles/calls/calls_instance.h
@@ -64,6 +64,9 @@ public:
[[nodiscard]] bool isQuitPrevent();
private:
+ using CallSound = Call::Delegate::CallSound;
+ using GroupCallSound = GroupCall::Delegate::GroupCallSound;
+
[[nodiscard]] not_null getCallDelegate() {
return static_cast(this);
}
@@ -73,6 +76,10 @@ private:
[[nodiscard]] DhConfig getDhConfig() const override {
return _dhConfig;
}
+
+ not_null ensureSoundLoaded(const QString &key);
+ void playSoundOnce(const QString &key);
+
void callFinished(not_null call) override;
void callFailed(not_null call) override;
void callRedial(not_null call) override;
@@ -81,15 +88,15 @@ private:
bool video) override {
requestPermissionsOrFail(std::move(onSuccess), video);
}
+ void callPlaySound(CallSound sound) override;
void groupCallFinished(not_null call) override;
void groupCallFailed(not_null call) override;
void groupCallRequestPermissionsOrFail(Fn onSuccess) override {
requestPermissionsOrFail(std::move(onSuccess), false);
}
+ void groupCallPlaySound(GroupCallSound sound) override;
- using Sound = Call::Delegate::Sound;
- void playSound(Sound sound) override;
void createCall(not_null user, Call::Type type, bool video);
void destroyCall(not_null call);
@@ -98,7 +105,9 @@ private:
const MTPInputGroupCall &inputCall);
void destroyGroupCall(not_null call);
- void requestPermissionOrFail(Platform::PermissionType type, Fn onSuccess);
+ void requestPermissionOrFail(
+ Platform::PermissionType type,
+ Fn onSuccess);
void refreshDhConfig();
void refreshServerConfig(not_null session);
@@ -132,9 +141,7 @@ private:
rpl::event_stream _currentGroupCallChanges;
std::unique_ptr _currentGroupCallPanel;
- std::unique_ptr _callConnectingTrack;
- std::unique_ptr _callEndedTrack;
- std::unique_ptr _callBusyTrack;
+ base::flat_map> _tracks;
};
diff --git a/Telegram/lib_ui b/Telegram/lib_ui
index 407079e5b..abb615a7c 160000
--- a/Telegram/lib_ui
+++ b/Telegram/lib_ui
@@ -1 +1 @@
-Subproject commit 407079e5b1cffdad2a08b0e00eafb78a175680c0
+Subproject commit abb615a7c9cb3a3992f67637592b481ccc50f17a