/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "calls/calls_group_settings.h" #include "calls/calls_group_call.h" #include "calls/calls_group_panel.h" // LeaveGroupCallBox. #include "calls/calls_instance.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" #include "boxes/single_choice_box.h" #include "webrtc/webrtc_audio_input_tester.h" #include "webrtc/webrtc_media_devices.h" #include "settings/settings_common.h" #include "settings/settings_calls.h" #include "main/main_session.h" #include "apiwrap.h" #include "styles/style_layers.h" #include "styles/style_calls.h" #include "styles/style_settings.h" #include namespace Calls { namespace { void SaveCallJoinMuted( not_null channel, uint64 callId, bool joinMuted) { const auto call = channel->call(); if (!call || call->id() != callId || !channel->canManageCall() || !call->canChangeJoinMuted() || call->joinMuted() == joinMuted) { return; } call->setJoinMutedLocally(joinMuted); channel->session().api().request(MTPphone_ToggleGroupCallSettings( MTP_flags(MTPphone_ToggleGroupCallSettings::Flag::f_join_muted), call->input(), MTP_bool(joinMuted) )).send(); } } // namespace void GroupCallSettingsBox( not_null box, not_null call) { using namespace Settings; const auto weakCall = base::make_weak(call.get()); const auto weakBox = Ui::MakeWeak(box); struct State { rpl::event_stream outputNameStream; rpl::event_stream inputNameStream; std::unique_ptr micTester; Ui::LevelMeter *micTestLevel = nullptr; float micLevel = 0.; Ui::Animations::Simple micLevelAnimation; base::Timer levelUpdateTimer; bool generatingLink = false; }; const auto state = box->lifetime().make_state(); const auto channel = call->channel(); const auto real = channel->call(); const auto id = call->id(); const auto goodReal = (real && real->id() == id); const auto layout = box->verticalLayout(); const auto &settings = Core::App().settings(); const auto joinMuted = goodReal ? real->joinMuted() : false; const auto canChangeJoinMuted = (goodReal && real->canChangeJoinMuted()); const auto addCheck = (channel->canManageCall() && canChangeJoinMuted); if (addCheck) { AddSkip(layout); } const auto muteJoined = addCheck ? AddButton( layout, tr::lng_group_call_new_muted(), st::groupCallSettingsButton)->toggleOn(rpl::single(joinMuted)) : nullptr; if (addCheck) { AddSkip(layout); } AddButtonWithLabel( layout, tr::lng_group_call_speakers(), rpl::single( CurrentAudioOutputName() ) | rpl::then( state->outputNameStream.events() ), st::groupCallSettingsButton )->addClickHandler([=] { box->getDelegate()->show(ChooseAudioOutputBox(crl::guard(box, [=]( const QString &id, const QString &name) { state->outputNameStream.fire_copy(name); }), &st::groupCallCheckbox, &st::groupCallRadio)); }); AddButtonWithLabel( layout, tr::lng_group_call_microphone(), rpl::single( CurrentAudioInputName() ) | rpl::then( state->inputNameStream.events() ), st::groupCallSettingsButton )->addClickHandler([=] { box->getDelegate()->show(ChooseAudioInputBox(crl::guard(box, [=]( const QString &id, const QString &name) { state->inputNameStream.fire_copy(name); if (state->micTester) { state->micTester->setDeviceId(id); } }), &st::groupCallCheckbox, &st::groupCallRadio)); }); state->micTestLevel = box->addRow( object_ptr( box.get(), st::groupCallLevelMeter), st::settingsLevelMeterPadding); state->micTestLevel->resize(QSize(0, st::defaultLevelMeter.height)); state->levelUpdateTimer.setCallback([=] { const auto was = state->micLevel; state->micLevel = state->micTester->getAndResetLevel(); state->micLevelAnimation.start([=] { state->micTestLevel->setValue( state->micLevelAnimation.value(state->micLevel)); }, was, state->micLevel, kMicTestAnimationDuration); }); AddSkip(layout); //AddDivider(layout); //AddSkip(layout); using namespace base::Platform; struct PushToTalkState { rpl::variable recordText = tr::lng_group_call_ptt_shortcut(); rpl::variable shortcutText; GlobalShortcut shortcut; bool recording = false; }; const auto manager = call->ensureGlobalShortcutManager(); if (manager) { const auto state = box->lifetime().make_state(); 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>( layout, object_ptr