mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Add start/end/reconnecting sounds to voice chats.
This commit is contained in:
parent
d301601360
commit
c5ad7c7c89
11 changed files with 109 additions and 46 deletions
|
@ -6,5 +6,8 @@
|
|||
<file alias="call_end.mp3">../../sounds/call_end.mp3</file>
|
||||
<file alias="call_incoming.mp3">../../sounds/call_incoming.mp3</file>
|
||||
<file alias="call_outgoing.mp3">../../sounds/call_outgoing.mp3</file>
|
||||
<file alias="group_call_start.mp3">../../sounds/group_call_start.mp3</file>
|
||||
<file alias="group_call_connect.mp3">../../sounds/group_call_connect.mp3</file>
|
||||
<file alias="group_call_end.mp3">../../sounds/group_call_end.mp3</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
BIN
Telegram/Resources/sounds/group_call_connect.mp3
Normal file
BIN
Telegram/Resources/sounds/group_call_connect.mp3
Normal file
Binary file not shown.
BIN
Telegram/Resources/sounds/group_call_end.mp3
Normal file
BIN
Telegram/Resources/sounds/group_call_end.mp3
Normal file
Binary file not shown.
BIN
Telegram/Resources/sounds/group_call_start.mp3
Normal file
BIN
Telegram/Resources/sounds/group_call_start.mp3
Normal file
Binary file not shown.
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,15 +62,16 @@ public:
|
|||
virtual void callFailed(not_null<Call*> call) = 0;
|
||||
virtual void callRedial(not_null<Call*> 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<void()> onSuccess,
|
||||
bool video) = 0;
|
||||
|
||||
virtual auto getVideoCapture()
|
||||
-> std::shared_ptr<tgcalls::VideoCaptureInterface> = 0;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -61,6 +61,13 @@ public:
|
|||
virtual void groupCallFailed(not_null<GroupCall*> call) = 0;
|
||||
virtual void groupCallRequestPermissionsOrFail(
|
||||
Fn<void()> 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*> _delegate;
|
||||
|
@ -191,7 +202,8 @@ private:
|
|||
std::shared_ptr<GlobalShortcutManager> _shortcutManager;
|
||||
std::shared_ptr<GlobalShortcutValue> _pushToTalk;
|
||||
base::Timer _pushToTalkCancelTimer;
|
||||
bool _pushToTalkStarted = false;
|
||||
base::Timer _connectingSoundTimer;
|
||||
bool _hadJoinedState = false;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
|
|
|
@ -98,35 +98,45 @@ void Instance::groupCallFailed(not_null<GroupCall*> 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<Media::Audio::Track*> 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*> call) {
|
||||
|
|
|
@ -64,6 +64,9 @@ public:
|
|||
[[nodiscard]] bool isQuitPrevent();
|
||||
|
||||
private:
|
||||
using CallSound = Call::Delegate::CallSound;
|
||||
using GroupCallSound = GroupCall::Delegate::GroupCallSound;
|
||||
|
||||
[[nodiscard]] not_null<Call::Delegate*> getCallDelegate() {
|
||||
return static_cast<Call::Delegate*>(this);
|
||||
}
|
||||
|
@ -73,6 +76,10 @@ private:
|
|||
[[nodiscard]] DhConfig getDhConfig() const override {
|
||||
return _dhConfig;
|
||||
}
|
||||
|
||||
not_null<Media::Audio::Track*> ensureSoundLoaded(const QString &key);
|
||||
void playSoundOnce(const QString &key);
|
||||
|
||||
void callFinished(not_null<Call*> call) override;
|
||||
void callFailed(not_null<Call*> call) override;
|
||||
void callRedial(not_null<Call*> call) override;
|
||||
|
@ -81,15 +88,15 @@ private:
|
|||
bool video) override {
|
||||
requestPermissionsOrFail(std::move(onSuccess), video);
|
||||
}
|
||||
void callPlaySound(CallSound sound) override;
|
||||
|
||||
void groupCallFinished(not_null<GroupCall*> call) override;
|
||||
void groupCallFailed(not_null<GroupCall*> call) override;
|
||||
void groupCallRequestPermissionsOrFail(Fn<void()> 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<UserData*> user, Call::Type type, bool video);
|
||||
void destroyCall(not_null<Call*> call);
|
||||
|
||||
|
@ -98,7 +105,9 @@ private:
|
|||
const MTPInputGroupCall &inputCall);
|
||||
void destroyGroupCall(not_null<GroupCall*> call);
|
||||
|
||||
void requestPermissionOrFail(Platform::PermissionType type, Fn<void()> onSuccess);
|
||||
void requestPermissionOrFail(
|
||||
Platform::PermissionType type,
|
||||
Fn<void()> onSuccess);
|
||||
|
||||
void refreshDhConfig();
|
||||
void refreshServerConfig(not_null<Main::Session*> session);
|
||||
|
@ -132,9 +141,7 @@ private:
|
|||
rpl::event_stream<GroupCall*> _currentGroupCallChanges;
|
||||
std::unique_ptr<GroupPanel> _currentGroupCallPanel;
|
||||
|
||||
std::unique_ptr<Media::Audio::Track> _callConnectingTrack;
|
||||
std::unique_ptr<Media::Audio::Track> _callEndedTrack;
|
||||
std::unique_ptr<Media::Audio::Track> _callBusyTrack;
|
||||
base::flat_map<QString, std::unique_ptr<Media::Audio::Track>> _tracks;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 407079e5b1cffdad2a08b0e00eafb78a175680c0
|
||||
Subproject commit abb615a7c9cb3a3992f67637592b481ccc50f17a
|
Loading…
Add table
Reference in a new issue