mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 23:27:09 +02:00
Add push-to-talk with global shortcut on Windows.
This commit is contained in:
parent
f4dfd738ec
commit
d41e93fb1c
12 changed files with 217 additions and 21 deletions
|
@ -1836,6 +1836,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_group_call_new_muted" = "Mute new members";
|
||||
"lng_group_call_speakers" = "Speakers";
|
||||
"lng_group_call_microphone" = "Microphone";
|
||||
"lng_group_call_push_to_talk" = "Push to Talk";
|
||||
"lng_group_call_ptt_shortcut" = "Edit Shortcut";
|
||||
"lng_group_call_ptt_recording" = "Stop Recording";
|
||||
"lng_group_call_share" = "Share Invite Link";
|
||||
"lng_group_call_end" = "End Voice Chat";
|
||||
"lng_group_call_join" = "Join";
|
||||
|
|
|
@ -641,20 +641,22 @@ groupCallCheckbox: Checkbox(defaultBoxCheckbox) {
|
|||
rippleBgActive: groupCallMembersBgRipple;
|
||||
}
|
||||
|
||||
groupCallSettingsButton: SettingsButton {
|
||||
groupCallSettingsToggle: Toggle(defaultToggle) {
|
||||
toggledBg: groupCallMembersBg;
|
||||
toggledFg: groupCallActiveFg;
|
||||
untoggledBg: groupCallMembersBg;
|
||||
untoggledFg: groupCallMemberNotJoinedStatus;
|
||||
}
|
||||
groupCallSettingsButton: SettingsButton(defaultSettingsButton) {
|
||||
textFg: groupCallMembersFg;
|
||||
textFgOver: groupCallMembersFg;
|
||||
textBg: groupCallMembersBg;
|
||||
textBgOver: groupCallMembersBgOver;
|
||||
|
||||
font: boxTextFont;
|
||||
rightLabel: FlatLabel(defaultSettingsRightLabel) {
|
||||
textFg: groupCallActiveFg;
|
||||
}
|
||||
|
||||
height: 20px;
|
||||
padding: margins(22px, 10px, 22px, 8px);
|
||||
|
||||
toggle: groupCallSettingsToggle;
|
||||
toggleOver: groupCallSettingsToggle;
|
||||
ripple: groupCallRipple;
|
||||
}
|
||||
groupCallSettingsAttentionButton: SettingsButton(groupCallSettingsButton) {
|
||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_channel.h"
|
||||
#include "data/data_group_call.h"
|
||||
#include "data/data_session.h"
|
||||
#include "base/platform/base_platform_global_shortcuts.h"
|
||||
|
||||
#include <tgcalls/group/GroupInstanceImpl.h>
|
||||
|
||||
|
@ -92,6 +93,11 @@ void GroupCall::setState(State state) {
|
|||
}
|
||||
_state = state;
|
||||
|
||||
if (_state.current() == State::Joined && !_pushToTalkStarted) {
|
||||
_pushToTalkStarted = true;
|
||||
applyGlobalShortcutChanges();
|
||||
}
|
||||
|
||||
if (false
|
||||
|| state == State::Ended
|
||||
|| state == State::Failed) {
|
||||
|
@ -706,6 +712,57 @@ std::variant<int, not_null<UserData*>> GroupCall::inviteUsers(
|
|||
return result;
|
||||
}
|
||||
|
||||
auto GroupCall::ensureGlobalShortcutManager()
|
||||
-> std::shared_ptr<GlobalShortcutManager> {
|
||||
if (!_shortcutManager) {
|
||||
_shortcutManager = base::Platform::CreateGlobalShortcutManager();
|
||||
}
|
||||
return _shortcutManager;
|
||||
}
|
||||
|
||||
void GroupCall::applyGlobalShortcutChanges() {
|
||||
auto &settings = Core::App().settings();
|
||||
if (!settings.groupCallPushToTalk()) {
|
||||
_shortcutManager = nullptr;
|
||||
_pushToTalk = nullptr;
|
||||
return;
|
||||
} else if (settings.groupCallPushToTalkShortcut().isEmpty()) {
|
||||
settings.setGroupCallPushToTalk(false);
|
||||
Core::App().saveSettingsDelayed();
|
||||
_shortcutManager = nullptr;
|
||||
_pushToTalk = nullptr;
|
||||
return;
|
||||
}
|
||||
ensureGlobalShortcutManager();
|
||||
if (!_shortcutManager) {
|
||||
settings.setGroupCallPushToTalk(false);
|
||||
Core::App().saveSettingsDelayed();
|
||||
_pushToTalk = nullptr;
|
||||
return;
|
||||
}
|
||||
const auto shortcut = _shortcutManager->shortcutFromSerialized(
|
||||
settings.groupCallPushToTalkShortcut());
|
||||
if (!shortcut) {
|
||||
settings.setGroupCallPushToTalkShortcut(QByteArray());
|
||||
settings.setGroupCallPushToTalk(false);
|
||||
Core::App().saveSettingsDelayed();
|
||||
_shortcutManager = nullptr;
|
||||
_pushToTalk = nullptr;
|
||||
return;
|
||||
}
|
||||
if (_pushToTalk) {
|
||||
if (shortcut->serialize() == _pushToTalk->serialize()) {
|
||||
return;
|
||||
}
|
||||
_shortcutManager->stopWatching(_pushToTalk);
|
||||
}
|
||||
_pushToTalk = shortcut;
|
||||
_shortcutManager->startWatching(_pushToTalk, [=](bool pressed) {
|
||||
if (_muted.current() != MuteState::ForceMuted) {
|
||||
setMuted(pressed ? MuteState::Active : MuteState::Muted);
|
||||
}
|
||||
});
|
||||
}
|
||||
//void GroupCall::setAudioVolume(bool input, float level) {
|
||||
// if (_instance) {
|
||||
// if (input) {
|
||||
|
|
|
@ -19,6 +19,13 @@ namespace tgcalls {
|
|||
class GroupInstanceImpl;
|
||||
} // namespace tgcalls
|
||||
|
||||
namespace base {
|
||||
namespace Platform {
|
||||
class GlobalShortcutManager;
|
||||
class GlobalShortcutValue;
|
||||
} // namespace Platform
|
||||
} // namespace base
|
||||
|
||||
namespace Calls {
|
||||
|
||||
enum class MuteState {
|
||||
|
@ -44,6 +51,8 @@ public:
|
|||
|
||||
};
|
||||
|
||||
using GlobalShortcutManager = base::Platform::GlobalShortcutManager;
|
||||
|
||||
GroupCall(
|
||||
not_null<Delegate*> delegate,
|
||||
not_null<ChannelData*> channel,
|
||||
|
@ -102,11 +111,16 @@ public:
|
|||
std::variant<int, not_null<UserData*>> inviteUsers(
|
||||
const std::vector<not_null<UserData*>> &users);
|
||||
|
||||
std::shared_ptr<GlobalShortcutManager> ensureGlobalShortcutManager();
|
||||
void applyGlobalShortcutChanges();
|
||||
|
||||
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||
return _lifetime;
|
||||
}
|
||||
|
||||
private:
|
||||
using GlobalShortcutValue = base::Platform::GlobalShortcutValue;
|
||||
|
||||
enum class FinishType {
|
||||
None,
|
||||
Ended,
|
||||
|
@ -160,6 +174,10 @@ private:
|
|||
|
||||
crl::time _lastSendProgressUpdate = 0;
|
||||
|
||||
std::shared_ptr<GlobalShortcutManager> _shortcutManager;
|
||||
std::shared_ptr<GlobalShortcutValue> _pushToTalk;
|
||||
bool _pushToTalkStarted = false;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
|
|
@ -10,10 +10,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "calls/calls_group_call.h"
|
||||
#include "calls/calls_group_panel.h" // LeaveGroupCallBox.
|
||||
#include "calls/calls_instance.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/level_meter.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "base/platform/base_platform_global_shortcuts.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_group_call.h"
|
||||
#include "core/application.h"
|
||||
|
@ -90,12 +92,10 @@ void GroupCallSettingsBox(
|
|||
AddSkip(layout);
|
||||
}
|
||||
const auto muteJoined = addCheck
|
||||
? box->addRow(object_ptr<Ui::Checkbox>(
|
||||
box.get(),
|
||||
? AddButton(
|
||||
layout,
|
||||
tr::lng_group_call_new_muted(),
|
||||
joinMuted,
|
||||
st::groupCallCheckbox,
|
||||
st::groupCallCheck))
|
||||
st::groupCallSettingsButton)->toggleOn(rpl::single(joinMuted))
|
||||
: nullptr;
|
||||
if (addCheck) {
|
||||
AddSkip(layout);
|
||||
|
@ -155,6 +155,97 @@ void GroupCallSettingsBox(
|
|||
});
|
||||
|
||||
AddSkip(layout);
|
||||
//AddDivider(layout);
|
||||
//AddSkip(layout);
|
||||
|
||||
using namespace base::Platform;
|
||||
struct PushToTalkState {
|
||||
rpl::variable<QString> recordText = tr::lng_group_call_ptt_shortcut();
|
||||
rpl::variable<QString> shortcutText;
|
||||
GlobalShortcut shortcut;
|
||||
bool recording = false;
|
||||
};
|
||||
const auto manager = call->ensureGlobalShortcutManager();
|
||||
if (manager) {
|
||||
const auto state = box->lifetime().make_state<PushToTalkState>();
|
||||
state->shortcut = manager->shortcutFromSerialized(
|
||||
settings.groupCallPushToTalkShortcut());
|
||||
state->shortcutText = state->shortcut
|
||||
? state->shortcut->toDisplayString()
|
||||
: QString();
|
||||
const auto pushToTalk = AddButton(
|
||||
layout,
|
||||
tr::lng_group_call_push_to_talk(),
|
||||
st::groupCallSettingsButton
|
||||
)->toggleOn(rpl::single(settings.groupCallPushToTalk()));
|
||||
const auto recordingWrap = layout->add(
|
||||
object_ptr<Ui::SlideWrap<Button>>(
|
||||
layout,
|
||||
object_ptr<Button>(
|
||||
layout,
|
||||
state->recordText.value(),
|
||||
st::groupCallSettingsButton)));
|
||||
const auto recording = recordingWrap->entity();
|
||||
CreateRightLabel(
|
||||
recording,
|
||||
state->shortcutText.value(),
|
||||
st::groupCallSettingsButton,
|
||||
state->recordText.value());
|
||||
const auto startRecording = [=] {
|
||||
state->recording = true;
|
||||
state->recordText = tr::lng_group_call_ptt_recording();
|
||||
manager->startRecording([=](GlobalShortcut shortcut) {
|
||||
state->shortcutText = shortcut->toDisplayString();
|
||||
}, [=](GlobalShortcut shortcut) {
|
||||
state->recording = false;
|
||||
state->shortcut = shortcut;
|
||||
state->shortcutText = shortcut
|
||||
? shortcut->toDisplayString()
|
||||
: QString();
|
||||
state->recordText = tr::lng_group_call_ptt_shortcut();
|
||||
Core::App().settings().setGroupCallPushToTalkShortcut(shortcut
|
||||
? shortcut->serialize()
|
||||
: QByteArray());
|
||||
Core::App().saveSettingsDelayed();
|
||||
});
|
||||
};
|
||||
const auto stopRecording = [=] {
|
||||
state->recording = false;
|
||||
state->recordText = tr::lng_group_call_ptt_shortcut();
|
||||
state->shortcutText = state->shortcut
|
||||
? state->shortcut->toDisplayString()
|
||||
: QString();
|
||||
manager->stopRecording();
|
||||
};
|
||||
recording->addClickHandler([=] {
|
||||
if (state->recording) {
|
||||
stopRecording();
|
||||
} else {
|
||||
startRecording();
|
||||
}
|
||||
});
|
||||
recordingWrap->toggle(
|
||||
settings.groupCallPushToTalk(),
|
||||
anim::type::instant);
|
||||
pushToTalk->toggledChanges(
|
||||
) | rpl::start_with_next([=](bool toggled) {
|
||||
if (!toggled) {
|
||||
stopRecording();
|
||||
}
|
||||
Core::App().settings().setGroupCallPushToTalk(toggled);
|
||||
Core::App().saveSettingsDelayed();
|
||||
recordingWrap->toggle(toggled, anim::type::normal);
|
||||
}, pushToTalk->lifetime());
|
||||
|
||||
box->boxClosing(
|
||||
) | rpl::start_with_next([=] {
|
||||
call->applyGlobalShortcutChanges();
|
||||
}, box->lifetime());
|
||||
}
|
||||
|
||||
AddSkip(layout);
|
||||
//AddDivider(layout);
|
||||
//AddSkip(layout);
|
||||
|
||||
const auto lookupLink = [=] {
|
||||
return channel->hasUsername()
|
||||
|
@ -226,8 +317,8 @@ void GroupCallSettingsBox(
|
|||
) | rpl::start_with_next([=] {
|
||||
if (canChangeJoinMuted
|
||||
&& muteJoined
|
||||
&& muteJoined->checked() != joinMuted) {
|
||||
SaveCallJoinMuted(channel, id, muteJoined->checked());
|
||||
&& muteJoined->toggled() != joinMuted) {
|
||||
SaveCallJoinMuted(channel, id, muteJoined->toggled());
|
||||
}
|
||||
}, box->lifetime());
|
||||
box->addButton(tr::lng_box_done(), [=] {
|
||||
|
|
|
@ -109,7 +109,9 @@ QByteArray Settings::serialize() const {
|
|||
<< qint32(_nativeWindowFrame.current() ? 1 : 0)
|
||||
<< qint32(_systemDarkModeEnabled.current() ? 1 : 0)
|
||||
<< _callVideoInputDeviceId
|
||||
<< qint32(_ipRevealWarning ? 1 : 0);
|
||||
<< qint32(_ipRevealWarning ? 1 : 0)
|
||||
<< qint32(_groupCallPushToTalk ? 1 : 0)
|
||||
<< _groupCallPushToTalkShortcut;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -177,6 +179,8 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
|||
qint32 nativeWindowFrame = _nativeWindowFrame.current() ? 1 : 0;
|
||||
qint32 systemDarkModeEnabled = _systemDarkModeEnabled.current() ? 1 : 0;
|
||||
qint32 ipRevealWarning = _ipRevealWarning ? 1 : 0;
|
||||
qint32 groupCallPushToTalk = _groupCallPushToTalk ? 1 : 0;
|
||||
QByteArray groupCallPushToTalkShortcut = _groupCallPushToTalkShortcut;
|
||||
|
||||
stream >> themesAccentColors;
|
||||
if (!stream.atEnd()) {
|
||||
|
@ -263,6 +267,11 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
|||
if (!stream.atEnd()) {
|
||||
stream >> ipRevealWarning;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream
|
||||
>> groupCallPushToTalk
|
||||
>> groupCallPushToTalkShortcut;
|
||||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("App Error: "
|
||||
"Bad data for Core::Settings::constructFromSerialized()"));
|
||||
|
@ -354,6 +363,8 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
|||
_notifyFromAll = (notifyFromAll == 1);
|
||||
_nativeWindowFrame = (nativeWindowFrame == 1);
|
||||
_systemDarkModeEnabled = (systemDarkModeEnabled == 1);
|
||||
_groupCallPushToTalk = (groupCallPushToTalk == 1);
|
||||
_groupCallPushToTalkShortcut = groupCallPushToTalkShortcut;
|
||||
}
|
||||
|
||||
bool Settings::chatWide() const {
|
||||
|
|
|
@ -217,6 +217,18 @@ public:
|
|||
void setCallAudioDuckingEnabled(bool value) {
|
||||
_callAudioDuckingEnabled = value;
|
||||
}
|
||||
[[nodiscard]] bool groupCallPushToTalk() const {
|
||||
return _groupCallPushToTalk;
|
||||
}
|
||||
void setGroupCallPushToTalk(bool value) {
|
||||
_groupCallPushToTalk = value;
|
||||
}
|
||||
[[nodiscard]] QByteArray groupCallPushToTalkShortcut() const {
|
||||
return _groupCallPushToTalkShortcut;
|
||||
}
|
||||
void setGroupCallPushToTalkShortcut(const QByteArray &serialized) {
|
||||
_groupCallPushToTalkShortcut = serialized;
|
||||
}
|
||||
[[nodiscard]] Window::Theme::AccentColors &themesAccentColors() {
|
||||
return _themesAccentColors;
|
||||
}
|
||||
|
@ -513,6 +525,8 @@ private:
|
|||
int _callOutputVolume = 100;
|
||||
int _callInputVolume = 100;
|
||||
bool _callAudioDuckingEnabled = true;
|
||||
bool _groupCallPushToTalk = false;
|
||||
QByteArray _groupCallPushToTalkShortcut;
|
||||
Window::Theme::AccentColors _themesAccentColors;
|
||||
bool _lastSeenWarningSeen = false;
|
||||
Ui::SendFilesWay _sendFilesWay;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 3562a43685fdac00c277292ce2c83d92132cc319
|
||||
Subproject commit 7d1df24be11eb6b3e6382735b73418b4a282bad4
|
|
@ -1 +1 @@
|
|||
Subproject commit 8aede3acc9d386484d2774316e9d1a3d0c265dd5
|
||||
Subproject commit 1b540b38ed78e9a3cba93e9ba4ce4525ab692277
|
|
@ -1 +1 @@
|
|||
Subproject commit 6fc06b5f9645005143f09f72e1c052a28d5f26ed
|
||||
Subproject commit cbe51722b73cfa9ff27bd59294b08aa5ee33c936
|
|
@ -1 +1 @@
|
|||
Subproject commit ab4ad89c4c709b2ec0f8296451d49c99d2ae4372
|
||||
Subproject commit 5f44304a305f9d02823e2d7ded9aadd59463e5a5
|
|
@ -1 +1 @@
|
|||
Subproject commit 52d52cad4e554dac1907224372d51fd40b9da92f
|
||||
Subproject commit 0ed2a6cc048e30ee8bacf7212f3f12f4f7ae2b5a
|
Loading…
Add table
Reference in a new issue