Add video/screencast pinned/unpinned toasts.
This commit is contained in:
parent
bcdfd2150d
commit
ba6cee6f81
|
@ -287,6 +287,8 @@ PRIVATE
|
|||
calls/group/calls_group_panel.h
|
||||
calls/group/calls_group_settings.cpp
|
||||
calls/group/calls_group_settings.h
|
||||
calls/group/calls_group_toasts.cpp
|
||||
calls/group/calls_group_toasts.h
|
||||
calls/group/calls_group_viewport.cpp
|
||||
calls/group/calls_group_viewport.h
|
||||
calls/group/calls_group_viewport_opengl.cpp
|
||||
|
|
|
@ -2130,6 +2130,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_group_call_recording_started" = "Voice chat recording started.";
|
||||
"lng_group_call_recording_stopped" = "Voice chat recording stopped.";
|
||||
"lng_group_call_recording_saved" = "Audio saved to Saved Messages.";
|
||||
"lng_group_call_pinned_camera_me" = "Your video is pinned.";
|
||||
"lng_group_call_pinned_screen_me" = "Your screencast is pinned.";
|
||||
"lng_group_call_pinned_camera" = "{user}'s video is pinned.";
|
||||
"lng_group_call_pinned_screen" = "{user}'s screencast is pinned.";
|
||||
"lng_group_call_unpinned_camera_me" = "Your video is unpinned.";
|
||||
"lng_group_call_unpinned_screen_me" = "Your screencast is unpinned.";
|
||||
"lng_group_call_unpinned_camera" = "{user}'s video is unpinned.";
|
||||
"lng_group_call_unpinned_screen" = "{user}'s screencast is unpinned.";
|
||||
"lng_group_call_sure_screencast" = "{user} is screensharing. This action will make your screencast pinned for all participants.";
|
||||
"lng_group_call_recording_start_sure" = "Do you want to start recording this chat and save the result into an audio file?\n\nOther members will see the chat is being recorded.";
|
||||
"lng_group_call_recording_stop_sure" = "Do you want to stop recording this chat?";
|
||||
"lng_group_call_recording_start_field" = "Recording Title";
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "calls/group/calls_group_settings.h"
|
||||
#include "calls/group/calls_group_menu.h"
|
||||
#include "calls/group/calls_group_viewport.h"
|
||||
#include "calls/group/calls_group_toasts.h"
|
||||
#include "calls/group/ui/desktop_capture_choose_source.h"
|
||||
#include "ui/platform/ui_platform_window_title.h"
|
||||
#include "ui/platform/ui_platform_utility.h"
|
||||
|
@ -27,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/layers/layer_manager.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
#include "ui/round_rect.h"
|
||||
#include "ui/special_buttons.h"
|
||||
|
@ -68,7 +70,6 @@ constexpr auto kRecordingOpacity = 0.6;
|
|||
constexpr auto kStartNoConfirmation = TimeId(10);
|
||||
constexpr auto kControlsBackgroundOpacity = 0.8;
|
||||
constexpr auto kOverrideActiveColorBgAlpha = 172;
|
||||
constexpr auto kErrorDuration = 2 * crl::time(1000);
|
||||
|
||||
class InviteController final : public ParticipantsBoxController {
|
||||
public:
|
||||
|
@ -421,7 +422,8 @@ Panel::Panel(not_null<GroupCall*> call)
|
|||
? Ui::CallMuteButtonType::ScheduledNotify
|
||||
: Ui::CallMuteButtonType::ScheduledSilent),
|
||||
}))
|
||||
, _hangup(widget(), st::groupCallHangup) {
|
||||
, _hangup(widget(), st::groupCallHangup)
|
||||
, _toasts(std::make_unique<Toasts>(this)) {
|
||||
_layerBg->setStyleOverrides(&st::groupCallBox, &st::groupCallLayerBox);
|
||||
_layerBg->setHideByBackgroundClick(true);
|
||||
|
||||
|
@ -441,7 +443,6 @@ Panel::Panel(not_null<GroupCall*> call)
|
|||
initControls();
|
||||
initLayout();
|
||||
showAndActivate();
|
||||
setupToasts();
|
||||
}
|
||||
|
||||
Panel::~Panel() {
|
||||
|
@ -456,12 +457,27 @@ void Panel::setupRealCallViewers() {
|
|||
}, _window->lifetime());
|
||||
}
|
||||
|
||||
not_null<GroupCall*> Panel::call() const {
|
||||
return _call;
|
||||
}
|
||||
|
||||
bool Panel::isActive() const {
|
||||
return _window->isActiveWindow()
|
||||
&& _window->isVisible()
|
||||
&& !(_window->windowState() & Qt::WindowMinimized);
|
||||
}
|
||||
|
||||
void Panel::showToast(TextWithEntities &&text, crl::time duration) {
|
||||
if (const auto strong = _lastToast.get()) {
|
||||
strong->hideAnimated();
|
||||
}
|
||||
_lastToast = Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = std::move(text),
|
||||
.duration = duration,
|
||||
});
|
||||
}
|
||||
|
||||
void Panel::minimize() {
|
||||
_window->setWindowState(_window->windowState() | Qt::WindowMinimized);
|
||||
}
|
||||
|
@ -814,19 +830,16 @@ void Panel::refreshVideoButtons(std::optional<bool> overrideWideMode) {
|
|||
}
|
||||
|
||||
void Panel::initShareAction() {
|
||||
const auto showBox = [=](object_ptr<Ui::BoxContent> next) {
|
||||
const auto showBoxCallback = [=](object_ptr<Ui::BoxContent> next) {
|
||||
_layerBg->showBox(std::move(next));
|
||||
};
|
||||
const auto showToast = [=](QString text) {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = { text },
|
||||
});
|
||||
const auto showToastCallback = [=](QString text) {
|
||||
showToast({ text });
|
||||
};
|
||||
auto [shareLinkCallback, shareLinkLifetime] = ShareInviteLinkAction(
|
||||
_peer,
|
||||
showBox,
|
||||
showToast);
|
||||
showBoxCallback,
|
||||
showToastCallback);
|
||||
_callShareLinkCallback = [=, callback = std::move(shareLinkCallback)] {
|
||||
if (_call->lookupReal()) {
|
||||
callback();
|
||||
|
@ -1199,118 +1212,6 @@ void Panel::toggleWideControls(bool shown) {
|
|||
});
|
||||
}
|
||||
|
||||
void Panel::setupToasts() {
|
||||
setupJoinAsChangedToasts();
|
||||
setupTitleChangedToasts();
|
||||
setupRequestedToSpeakToasts();
|
||||
setupAllowedToSpeakToasts();
|
||||
setupErrorToasts();
|
||||
}
|
||||
|
||||
void Panel::setupJoinAsChangedToasts() {
|
||||
_call->rejoinEvents(
|
||||
) | rpl::filter([](RejoinEvent event) {
|
||||
return (event.wasJoinAs != event.nowJoinAs);
|
||||
}) | rpl::map([=] {
|
||||
return _call->stateValue() | rpl::filter([](State state) {
|
||||
return (state == State::Joined);
|
||||
}) | rpl::take(1);
|
||||
}) | rpl::flatten_latest() | rpl::start_with_next([=] {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = tr::lng_group_call_join_as_changed(
|
||||
tr::now,
|
||||
lt_name,
|
||||
Ui::Text::Bold(_call->joinAs()->name),
|
||||
Ui::Text::WithEntities),
|
||||
});
|
||||
}, widget()->lifetime());
|
||||
}
|
||||
|
||||
void Panel::setupTitleChangedToasts() {
|
||||
_call->titleChanged(
|
||||
) | rpl::filter([=] {
|
||||
return (_call->lookupReal() != nullptr);
|
||||
}) | rpl::map([=] {
|
||||
return _peer->groupCall()->title().isEmpty()
|
||||
? _peer->name
|
||||
: _peer->groupCall()->title();
|
||||
}) | rpl::start_with_next([=](const QString &title) {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = tr::lng_group_call_title_changed(
|
||||
tr::now,
|
||||
lt_title,
|
||||
Ui::Text::Bold(title),
|
||||
Ui::Text::WithEntities),
|
||||
});
|
||||
}, widget()->lifetime());
|
||||
}
|
||||
|
||||
void Panel::setupAllowedToSpeakToasts() {
|
||||
_call->allowedToSpeakNotifications(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (isActive()) {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = { tr::lng_group_call_can_speak_here(tr::now) },
|
||||
});
|
||||
} else {
|
||||
const auto real = _call->lookupReal();
|
||||
const auto name = (real && !real->title().isEmpty())
|
||||
? real->title()
|
||||
: _peer->name;
|
||||
Ui::ShowMultilineToast({
|
||||
.text = tr::lng_group_call_can_speak(
|
||||
tr::now,
|
||||
lt_chat,
|
||||
Ui::Text::Bold(name),
|
||||
Ui::Text::WithEntities),
|
||||
});
|
||||
}
|
||||
}, widget()->lifetime());
|
||||
}
|
||||
|
||||
void Panel::setupRequestedToSpeakToasts() {
|
||||
_call->mutedValue(
|
||||
) | rpl::combine_previous(
|
||||
) | rpl::start_with_next([=](MuteState was, MuteState now) {
|
||||
if (was == MuteState::ForceMuted && now == MuteState::RaisedHand) {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = tr::lng_group_call_tooltip_raised_hand(tr::now),
|
||||
});
|
||||
}
|
||||
}, widget()->lifetime());
|
||||
}
|
||||
|
||||
void Panel::setupErrorToasts() {
|
||||
_call->errors(
|
||||
) | rpl::start_with_next([=](Error error) {
|
||||
const auto key = [&] {
|
||||
switch (error) {
|
||||
case Error::NoCamera: return tr::lng_call_error_no_camera;
|
||||
case Error::ScreenFailed:
|
||||
return tr::lng_group_call_failed_screen;
|
||||
case Error::MutedNoCamera:
|
||||
return tr::lng_group_call_muted_no_camera;
|
||||
case Error::MutedNoScreen:
|
||||
return tr::lng_group_call_muted_no_screen;
|
||||
case Error::DisabledNoCamera:
|
||||
return tr::lng_group_call_chat_no_camera;
|
||||
case Error::DisabledNoScreen:
|
||||
return tr::lng_group_call_chat_no_screen;
|
||||
}
|
||||
Unexpected("Error in Calls::Group::Panel::setupErrorToasts.");
|
||||
}();
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = { key(tr::now) },
|
||||
.duration = kErrorDuration,
|
||||
});
|
||||
}, widget()->lifetime());
|
||||
}
|
||||
|
||||
void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
||||
const auto validateRecordingMark = [=](bool recording) {
|
||||
if (!recording && _recordingMark) {
|
||||
|
@ -1328,10 +1229,7 @@ void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
|||
const auto skip = st::groupCallRecordingMarkSkip;
|
||||
_recordingMark->resize(size + 2 * skip, size + 2 * skip);
|
||||
_recordingMark->setClickedCallback([=] {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = { tr::lng_group_call_is_recorded(tr::now) },
|
||||
});
|
||||
showToast({ tr::lng_group_call_is_recorded(tr::now) });
|
||||
});
|
||||
const auto animate = [=] {
|
||||
const auto opaque = state->opaque;
|
||||
|
@ -1367,16 +1265,13 @@ void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
|||
) | rpl::distinct_until_changed(
|
||||
) | rpl::start_with_next([=](bool recorded) {
|
||||
validateRecordingMark(recorded);
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = (recorded
|
||||
? tr::lng_group_call_recording_started
|
||||
: _call->recordingStoppedByMe()
|
||||
? tr::lng_group_call_recording_saved
|
||||
: tr::lng_group_call_recording_stopped)(
|
||||
tr::now,
|
||||
Ui::Text::RichLangValue),
|
||||
});
|
||||
showToast((recorded
|
||||
? tr::lng_group_call_recording_started
|
||||
: _call->recordingStoppedByMe()
|
||||
? tr::lng_group_call_recording_saved
|
||||
: tr::lng_group_call_recording_stopped)(
|
||||
tr::now,
|
||||
Ui::Text::RichLangValue));
|
||||
}, widget()->lifetime());
|
||||
validateRecordingMark(real->recordStartDate() != 0);
|
||||
|
||||
|
@ -1448,20 +1343,17 @@ void Panel::chooseJoinAs() {
|
|||
const auto callback = [=](JoinInfo info) {
|
||||
_call->rejoinAs(info);
|
||||
};
|
||||
const auto showBox = [=](object_ptr<Ui::BoxContent> next) {
|
||||
const auto showBoxCallback = [=](object_ptr<Ui::BoxContent> next) {
|
||||
_layerBg->showBox(std::move(next));
|
||||
};
|
||||
const auto showToast = [=](QString text) {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = { text },
|
||||
});
|
||||
const auto showToastCallback = [=](QString text) {
|
||||
showToast({ text });
|
||||
};
|
||||
_joinAsProcess.start(
|
||||
_peer,
|
||||
context,
|
||||
showBox,
|
||||
showToast,
|
||||
showBoxCallback,
|
||||
showToastCallback,
|
||||
callback,
|
||||
_call->joinAs());
|
||||
}
|
||||
|
@ -1578,24 +1470,18 @@ void Panel::addMembers() {
|
|||
}
|
||||
const auto result = call->inviteUsers(users);
|
||||
if (const auto user = std::get_if<not_null<UserData*>>(&result)) {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = tr::lng_group_call_invite_done_user(
|
||||
tr::now,
|
||||
lt_user,
|
||||
Ui::Text::Bold((*user)->firstName),
|
||||
Ui::Text::WithEntities),
|
||||
});
|
||||
showToast(tr::lng_group_call_invite_done_user(
|
||||
tr::now,
|
||||
lt_user,
|
||||
Ui::Text::Bold((*user)->firstName),
|
||||
Ui::Text::WithEntities));
|
||||
} else if (const auto count = std::get_if<int>(&result)) {
|
||||
if (*count > 0) {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = widget(),
|
||||
.text = tr::lng_group_call_invite_done_many(
|
||||
tr::now,
|
||||
lt_count,
|
||||
*count,
|
||||
Ui::Text::RichLangValue),
|
||||
});
|
||||
showToast(tr::lng_group_call_invite_done_many(
|
||||
tr::now,
|
||||
lt_count,
|
||||
*count,
|
||||
Ui::Text::RichLangValue));
|
||||
}
|
||||
} else {
|
||||
Unexpected("Result in GroupCall::inviteUsers.");
|
||||
|
|
|
@ -42,6 +42,9 @@ class ScrollArea;
|
|||
class GenericBox;
|
||||
class LayerManager;
|
||||
class GroupCallScheduledLeft;
|
||||
namespace Toast {
|
||||
class Instance;
|
||||
} // namespace Toast
|
||||
namespace Platform {
|
||||
class TitleControls;
|
||||
} // namespace Platform
|
||||
|
@ -54,6 +57,7 @@ struct CallBodyLayout;
|
|||
|
||||
namespace Calls::Group {
|
||||
|
||||
class Toasts;
|
||||
class Members;
|
||||
class Viewport;
|
||||
enum class PanelMode;
|
||||
|
@ -63,7 +67,11 @@ public:
|
|||
Panel(not_null<GroupCall*> call);
|
||||
~Panel();
|
||||
|
||||
[[nodiscard]] not_null<GroupCall*> call() const;
|
||||
[[nodiscard]] bool isActive() const;
|
||||
|
||||
void showToast(TextWithEntities &&text, crl::time duration = 0);
|
||||
|
||||
void minimize();
|
||||
void close();
|
||||
void showAndActivate();
|
||||
|
@ -88,12 +96,6 @@ private:
|
|||
void setupScheduledLabels(rpl::producer<TimeId> date);
|
||||
void setupMembers();
|
||||
void setupVideo(not_null<Viewport*> viewport);
|
||||
void setupToasts();
|
||||
void setupJoinAsChangedToasts();
|
||||
void setupTitleChangedToasts();
|
||||
void setupRequestedToSpeakToasts();
|
||||
void setupAllowedToSpeakToasts();
|
||||
void setupErrorToasts();
|
||||
void setupRealMuteButtonState(not_null<Data::GroupCall*> real);
|
||||
|
||||
bool handleClose();
|
||||
|
@ -196,6 +198,9 @@ private:
|
|||
object_ptr<Ui::ImportantTooltip> _niceTooltip = { nullptr };
|
||||
Fn<void()> _callShareLinkCallback;
|
||||
|
||||
const std::unique_ptr<Toasts> _toasts;
|
||||
base::weak_ptr<Ui::Toast::Instance> _lastToast;
|
||||
|
||||
rpl::lifetime _peerLifetime;
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
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/group/calls_group_toasts.h"
|
||||
|
||||
#include "calls/group/calls_group_call.h"
|
||||
#include "calls/group/calls_group_common.h"
|
||||
#include "calls/group/calls_group_panel.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_group_call.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
#include "lang/lang_keys.h"
|
||||
|
||||
namespace Calls::Group {
|
||||
namespace {
|
||||
|
||||
constexpr auto kErrorDuration = 2 * crl::time(1000);
|
||||
|
||||
using State = GroupCall::State;
|
||||
|
||||
} // namespace
|
||||
|
||||
Toasts::Toasts(not_null<Panel*> panel)
|
||||
: _panel(panel)
|
||||
, _call(panel->call()) {
|
||||
setup();
|
||||
}
|
||||
|
||||
void Toasts::setup() {
|
||||
setupJoinAsChanged();
|
||||
setupTitleChanged();
|
||||
setupRequestedToSpeak();
|
||||
setupAllowedToSpeak();
|
||||
setupPinnedVideo();
|
||||
setupError();
|
||||
}
|
||||
|
||||
void Toasts::setupJoinAsChanged() {
|
||||
_call->rejoinEvents(
|
||||
) | rpl::filter([](RejoinEvent event) {
|
||||
return (event.wasJoinAs != event.nowJoinAs);
|
||||
}) | rpl::map([=] {
|
||||
return _call->stateValue() | rpl::filter([](State state) {
|
||||
return (state == State::Joined);
|
||||
}) | rpl::take(1);
|
||||
}) | rpl::flatten_latest() | rpl::start_with_next([=] {
|
||||
_panel->showToast(tr::lng_group_call_join_as_changed(
|
||||
tr::now,
|
||||
lt_name,
|
||||
Ui::Text::Bold(_call->joinAs()->name),
|
||||
Ui::Text::WithEntities));
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
void Toasts::setupTitleChanged() {
|
||||
_call->titleChanged(
|
||||
) | rpl::filter([=] {
|
||||
return (_call->lookupReal() != nullptr);
|
||||
}) | rpl::map([=] {
|
||||
const auto peer = _call->peer();
|
||||
return peer->groupCall()->title().isEmpty()
|
||||
? peer->name
|
||||
: peer->groupCall()->title();
|
||||
}) | rpl::start_with_next([=](const QString &title) {
|
||||
_panel->showToast(tr::lng_group_call_title_changed(
|
||||
tr::now,
|
||||
lt_title,
|
||||
Ui::Text::Bold(title),
|
||||
Ui::Text::WithEntities));
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
void Toasts::setupAllowedToSpeak() {
|
||||
_call->allowedToSpeakNotifications(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (_panel->isActive()) {
|
||||
_panel->showToast({
|
||||
tr::lng_group_call_can_speak_here(tr::now),
|
||||
});
|
||||
} else {
|
||||
const auto real = _call->lookupReal();
|
||||
const auto name = (real && !real->title().isEmpty())
|
||||
? real->title()
|
||||
: _call->peer()->name;
|
||||
Ui::ShowMultilineToast({
|
||||
.text = tr::lng_group_call_can_speak(
|
||||
tr::now,
|
||||
lt_chat,
|
||||
Ui::Text::Bold(name),
|
||||
Ui::Text::WithEntities),
|
||||
});
|
||||
}
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
void Toasts::setupPinnedVideo() {
|
||||
_call->videoEndpointPinnedValue(
|
||||
) | rpl::map([=](bool pinned) {
|
||||
return pinned
|
||||
? _call->videoEndpointLargeValue()
|
||||
: rpl::single(_call->videoEndpointLarge());
|
||||
}) | rpl::flatten_latest(
|
||||
) | rpl::start_with_next([=](const VideoEndpoint &endpoint) {
|
||||
const auto pinned = _call->videoEndpointPinned();
|
||||
const auto peer = endpoint.peer;
|
||||
if (!peer) {
|
||||
return;
|
||||
}
|
||||
const auto text = [&] {
|
||||
const auto me = (peer == _call->joinAs());
|
||||
const auto camera = (endpoint.type == VideoEndpointType::Camera);
|
||||
if (me) {
|
||||
const auto key = camera
|
||||
? (pinned
|
||||
? tr::lng_group_call_pinned_camera_me
|
||||
: tr::lng_group_call_unpinned_camera_me)
|
||||
: (pinned
|
||||
? tr::lng_group_call_pinned_screen_me
|
||||
: tr::lng_group_call_unpinned_screen_me);
|
||||
return key(tr::now);
|
||||
}
|
||||
const auto key = camera
|
||||
? (pinned
|
||||
? tr::lng_group_call_pinned_camera
|
||||
: tr::lng_group_call_unpinned_camera)
|
||||
: (pinned
|
||||
? tr::lng_group_call_pinned_screen
|
||||
: tr::lng_group_call_unpinned_screen);
|
||||
return key(tr::now, lt_user, peer->shortName());
|
||||
}();
|
||||
_panel->showToast({ text });
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
void Toasts::setupRequestedToSpeak() {
|
||||
_call->mutedValue(
|
||||
) | rpl::combine_previous(
|
||||
) | rpl::start_with_next([=](MuteState was, MuteState now) {
|
||||
if (was == MuteState::ForceMuted && now == MuteState::RaisedHand) {
|
||||
_panel->showToast({
|
||||
tr::lng_group_call_tooltip_raised_hand(tr::now),
|
||||
});
|
||||
}
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
void Toasts::setupError() {
|
||||
_call->errors(
|
||||
) | rpl::start_with_next([=](Error error) {
|
||||
const auto key = [&] {
|
||||
switch (error) {
|
||||
case Error::NoCamera: return tr::lng_call_error_no_camera;
|
||||
case Error::ScreenFailed:
|
||||
return tr::lng_group_call_failed_screen;
|
||||
case Error::MutedNoCamera:
|
||||
return tr::lng_group_call_muted_no_camera;
|
||||
case Error::MutedNoScreen:
|
||||
return tr::lng_group_call_muted_no_screen;
|
||||
case Error::DisabledNoCamera:
|
||||
return tr::lng_group_call_chat_no_camera;
|
||||
case Error::DisabledNoScreen:
|
||||
return tr::lng_group_call_chat_no_screen;
|
||||
}
|
||||
Unexpected("Error in Calls::Group::Toasts::setupErrorToasts.");
|
||||
}();
|
||||
_panel->showToast({ key(tr::now) }, kErrorDuration);
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
} // namespace Calls::Group
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
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
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Calls {
|
||||
class GroupCall;
|
||||
} // namespace Calls
|
||||
|
||||
namespace Calls::Group {
|
||||
|
||||
class Panel;
|
||||
|
||||
class Toasts final {
|
||||
public:
|
||||
explicit Toasts(not_null<Panel*> panel);
|
||||
|
||||
private:
|
||||
void setup();
|
||||
void setupJoinAsChanged();
|
||||
void setupTitleChanged();
|
||||
void setupRequestedToSpeak();
|
||||
void setupAllowedToSpeak();
|
||||
void setupPinnedVideo();
|
||||
void setupError();
|
||||
|
||||
const not_null<Panel*> _panel;
|
||||
const not_null<GroupCall*> _call;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Calls::Group
|
|
@ -1139,7 +1139,7 @@ void CallMuteButton::overridesColors(
|
|||
const auto toInactive = IsInactive(toType);
|
||||
const auto fromInactive = IsInactive(fromType);
|
||||
if (toInactive && (progress == 1)) {
|
||||
_colorOverrides.fire({ std::nullopt, std::nullopt });
|
||||
_colorOverrides = CallButtonColors();
|
||||
return;
|
||||
}
|
||||
const auto &fromStops = _colors.find(fromType)->second.stops;
|
||||
|
@ -1158,11 +1158,11 @@ void CallMuteButton::overridesColors(
|
|||
}
|
||||
const auto resultBg = anim::color(from, to, progress);
|
||||
const auto resultRipple = anim::color(fromRipple, toRipple, progress);
|
||||
_colorOverrides.fire({ resultBg, resultRipple });
|
||||
_colorOverrides = CallButtonColors{ resultBg, resultRipple };
|
||||
}
|
||||
|
||||
rpl::producer<CallButtonColors> CallMuteButton::colorOverrides() const {
|
||||
return _colorOverrides.events();
|
||||
return _colorOverrides.value();
|
||||
}
|
||||
|
||||
not_null<RpWidget*> CallMuteButton::outer() const {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "ui/effects/cross_line.h"
|
||||
#include "ui/effects/gradient.h"
|
||||
#include "ui/effects/radial_animation.h"
|
||||
#include "ui/widgets/call_button.h"
|
||||
#include "ui/widgets/tooltip.h"
|
||||
#include "lottie/lottie_icon.h"
|
||||
|
||||
|
@ -31,8 +32,6 @@ class FlatLabel;
|
|||
class RpWidget;
|
||||
class AnimatedLabel;
|
||||
|
||||
struct CallButtonColors;
|
||||
|
||||
enum class CallMuteButtonType {
|
||||
Connecting,
|
||||
Active,
|
||||
|
@ -179,7 +178,7 @@ private:
|
|||
Animations::Simple _switchAnimation;
|
||||
Animations::Simple _shakeAnimation;
|
||||
|
||||
rpl::event_stream<CallButtonColors> _colorOverrides;
|
||||
rpl::variable<CallButtonColors> _colorOverrides;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Ui {
|
||||
|
||||
void ShowMultilineToast(MultilineToastArgs &&args) {
|
||||
base::weak_ptr<Toast::Instance> ShowMultilineToast(
|
||||
MultilineToastArgs &&args) {
|
||||
auto config = Ui::Toast::Config{
|
||||
.text = std::move(args.text),
|
||||
.st = &st::defaultMultilineToast,
|
||||
|
@ -21,11 +22,9 @@ void ShowMultilineToast(MultilineToastArgs &&args) {
|
|||
: Ui::Toast::kDefaultDuration),
|
||||
.multiline = true,
|
||||
};
|
||||
if (args.parentOverride) {
|
||||
Ui::Toast::Show(args.parentOverride, std::move(config));
|
||||
} else {
|
||||
Ui::Toast::Show(std::move(config));
|
||||
}
|
||||
return args.parentOverride
|
||||
? Ui::Toast::Show(args.parentOverride, std::move(config))
|
||||
: Ui::Toast::Show(std::move(config));
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -8,8 +8,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "ui/text/text_entity.h"
|
||||
#include "base/weak_ptr.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace Toast {
|
||||
class Instance;
|
||||
} // namespace Toast
|
||||
|
||||
struct MultilineToastArgs {
|
||||
QWidget *parentOverride = nullptr;
|
||||
|
@ -17,6 +21,7 @@ struct MultilineToastArgs {
|
|||
crl::time duration = 0;
|
||||
};
|
||||
|
||||
void ShowMultilineToast(MultilineToastArgs &&args);
|
||||
base::weak_ptr<Toast::Instance> ShowMultilineToast(
|
||||
MultilineToastArgs &&args);
|
||||
|
||||
} // namespace Ui
|
||||
|
|
Loading…
Reference in New Issue