Add edit voice chat title.

This commit is contained in:
John Preston 2021-03-05 20:59:35 +04:00
parent b670ca2a51
commit bc43168ca7
8 changed files with 158 additions and 20 deletions

View File

@ -505,6 +505,27 @@ groupCallMultiSelect: MultiSelect(defaultMultiSelect) {
}
}
groupCallField: InputField(defaultInputField) {
textMargins: margins(2px, 7px, 2px, 0px);
textBg: transparent;
textFg: groupCallMembersFg;
placeholderFg: groupCallMemberNotJoinedStatus;
placeholderFgActive: groupCallMemberNotJoinedStatus;
placeholderFgError: groupCallMemberNotJoinedStatus;
placeholderMargins: margins(2px, 0px, 2px, 0px);
placeholderScale: 0.;
placeholderFont: normalFont;
heightMin: 32px;
borderFg: inputBorderFg;
borderFgActive: groupCallMemberInactiveStatus;
borderFgError: activeLineFgError;
menu: groupCallPopupMenu;
}
groupCallMembersTop: 62px;
groupCallTitleTop: 14px;
groupCallSubtitleTop: 33px;

View File

@ -705,6 +705,22 @@ void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) {
}
}
void GroupCall::changeTitle(const QString &title) {
const auto real = _peer->groupCall();
if (!real || real->id() != _id || real->title() == title) {
return;
}
real->setTitle(title);
_api.request(MTPphone_EditGroupCallTitle(
inputCall(),
MTP_string(title)
)).done([=](const MTPUpdates &result) {
_peer->session().api().applyUpdates(result);
}).fail([=](const RPCError &error) {
}).send();
}
void GroupCall::createAndStartController() {
const auto &settings = Core::App().settings();

View File

@ -115,6 +115,7 @@ public:
void join(const MTPInputGroupCall &inputCall);
void handleUpdate(const MTPGroupCall &call);
void handleUpdate(const MTPDupdateGroupCallParticipants &data);
void changeTitle(const QString &title);
void setMuted(MuteState mute);
[[nodiscard]] MuteState muted() const {

View File

@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h"
#include "data/data_group_call.h"
#include "data/data_session.h"
#include "data/data_changes.h"
#include "main/main_session.h"
#include "base/event_filter.h"
#include "boxes/peers/edit_participants_box.h"
@ -324,6 +325,7 @@ GroupPanel::GroupPanel(not_null<GroupCall*> call)
_peer,
_window->lifetime(),
[=](not_null<ChannelData*> channel) { migrate(channel); });
setupRealCallViewers(call);
initWindow();
initWidget();
@ -334,6 +336,22 @@ GroupPanel::GroupPanel(not_null<GroupCall*> call)
GroupPanel::~GroupPanel() = default;
void GroupPanel::setupRealCallViewers(not_null<GroupCall*> call) {
const auto peer = call->peer();
peer->session().changes().peerFlagsValue(
peer,
Data::PeerUpdate::Flag::GroupCall
) | rpl::map([=] {
return peer->groupCall();
}) | rpl::filter([=](Data::GroupCall *real) {
return _call && real && (real->id() == _call->id());
}) | rpl::take(
1
) | rpl::start_with_next([=](not_null<Data::GroupCall*> real) {
subscribeToChanges(real);
}, _window->lifetime());
}
bool GroupPanel::isActive() const {
return _window->isActiveWindow()
&& _window->isVisible()
@ -565,6 +583,10 @@ void GroupPanel::initWithCall(GroupCall *call) {
}, _callLifetime);
}
void GroupPanel::subscribeToChanges(not_null<Data::GroupCall*> real) {
_titleText = real->titleValue();
}
void GroupPanel::addMembers() {
const auto real = _peer->groupCall();
if (!_call || !real || real->id() != _call->id()) {
@ -829,32 +851,26 @@ void GroupPanel::updateControlsGeometry() {
}
void GroupPanel::refreshTitle() {
if (const auto titleRect = computeTitleRect()) {
if (computeTitleRect().has_value()) {
if (!_title) {
auto text = rpl::combine(
Info::Profile::NameValue(_peer),
_titleText.value()
) | rpl::map([=](
const TextWithEntities &name,
const QString &title) {
return title.isEmpty() ? name.text : title;
}) | rpl::after_next([=] {
refreshTitleGeometry();
});
_title.create(
widget(),
Info::Profile::NameValue(_peer),
rpl::duplicate(text),
st::groupCallTitleLabel);
_title->show();
_title->setAttribute(Qt::WA_TransparentForMouseEvents);
}
const auto best = _title->naturalWidth();
const auto from = (widget()->width() - best) / 2;
const auto top = st::groupCallTitleTop;
const auto left = titleRect->x();
if (from >= left && from + best <= left + titleRect->width()) {
_title->resizeToWidth(best);
_title->moveToLeft(from, top);
} else if (titleRect->width() < best) {
_title->resizeToWidth(titleRect->width());
_title->moveToLeft(left, top);
} else if (from < left) {
_title->resizeToWidth(best);
_title->moveToLeft(left, top);
} else {
_title->resizeToWidth(best);
_title->moveToLeft(left + titleRect->width() - best, top);
}
refreshTitleGeometry();
} else if (_title) {
_title.destroy();
}
@ -879,6 +895,30 @@ void GroupPanel::refreshTitle() {
top);
}
void GroupPanel::refreshTitleGeometry() {
const auto titleRect = computeTitleRect();
if (!_title || !titleRect) {
return;
}
const auto best = _title->naturalWidth();
const auto from = (widget()->width() - best) / 2;
const auto top = st::groupCallTitleTop;
const auto left = titleRect->x();
if (from >= left && from + best <= left + titleRect->width()) {
_title->resizeToWidth(best);
_title->moveToLeft(from, top);
} else if (titleRect->width() < best) {
_title->resizeToWidth(titleRect->width());
_title->moveToLeft(left, top);
} else if (from < left) {
_title->resizeToWidth(best);
_title->moveToLeft(left, top);
} else {
_title->resizeToWidth(best);
_title->moveToLeft(left + titleRect->width() - best, top);
}
}
void GroupPanel::paint(QRect clip) {
Painter p(widget());

View File

@ -19,6 +19,7 @@ class Image;
namespace Data {
class PhotoMedia;
class CloudImageView;
class GroupCall;
} // namespace Data
namespace Ui {
@ -100,6 +101,9 @@ private:
[[nodiscard]] int computeMembersListTop() const;
[[nodiscard]] std::optional<QRect> computeTitleRect() const;
void refreshTitle();
void refreshTitleGeometry();
void setupRealCallViewers(not_null<GroupCall*> call);
void subscribeToChanges(not_null<Data::GroupCall*> real);
void migrate(not_null<ChannelData*> channel);
void subscribeToPeerChanges();
@ -119,6 +123,7 @@ private:
object_ptr<Ui::FlatLabel> _title = { nullptr };
object_ptr<Ui::FlatLabel> _subtitle = { nullptr };
object_ptr<GroupMembers> _members;
rpl::variable<QString> _titleText;
object_ptr<Ui::CallButton> _settings;
std::unique_ptr<Ui::CallMuteButton> _mute;

View File

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/level_meter.h"
#include "ui/widgets/continuous_sliders.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/text/text_utilities.h"
#include "ui/toast/toast.h"
@ -84,6 +85,28 @@ void SaveCallJoinMuted(
QString::number(delay / 1000., 'f', 2));
}
void EditGroupCallTitleBox(
not_null<Ui::GenericBox*> box,
const QString &placeholder,
const QString &title,
Fn<void(QString)> done) {
box->setTitle(tr::lng_group_call_edit_title());
const auto input = box->addRow(object_ptr<Ui::InputField>(
box,
st::groupCallField,
rpl::single(placeholder),
title));
box->setFocusCallback([=] {
input->setFocusFast();
});
box->addButton(tr::lng_settings_save(), [=] {
const auto result = input->getLastText();
box->closeBox();
done(result);
});
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
}
} // namespace
void GroupCallSettingsBox(
@ -119,6 +142,7 @@ void GroupCallSettingsBox(
const auto canChangeJoinMuted = (goodReal && real->canChangeJoinMuted());
const auto addCheck = (peer->canManageGroupCall() && canChangeJoinMuted);
const auto addEditJoinAs = (call->possibleJoinAs().size() > 1);
const auto addEditTitle = peer->canManageGroupCall();
if (addCheck || addEditJoinAs) {
AddSkip(layout);
}
@ -128,6 +152,12 @@ void GroupCallSettingsBox(
tr::lng_group_call_display_as_header(),
st::groupCallSettingsButton).get()
: nullptr;
const auto editTitle = (goodReal && addEditTitle)
? AddButton(
layout,
tr::lng_group_call_edit_title(),
st::groupCallSettingsButton).get()
: nullptr;
if (editJoinAs) {
editJoinAs->setClickedCallback([=] {
const auto context = Group::ChooseJoinAsProcess::Context::Switch;
@ -145,6 +175,18 @@ void GroupCallSettingsBox(
call->joinAs());
});
}
if (editTitle) {
editTitle->setClickedCallback([=] {
const auto done = [=](const QString &title) {
call->changeTitle(title);
};
box->getDelegate()->show(Box(
EditGroupCallTitleBox,
peer->name,
goodReal ? real->title() : QString(),
done));
});
}
const auto muteJoined = addCheck
? AddButton(
layout,

View File

@ -175,10 +175,12 @@ void GroupCall::applyUpdate(const MTPGroupCall &update) {
void GroupCall::applyCall(const MTPGroupCall &call, bool force) {
call.match([&](const MTPDgroupCall &data) {
const auto title = qs(data.vtitle().value_or_empty());
const auto changed = (_version != data.vversion().v)
|| (_fullCount.current() != data.vparticipants_count().v)
|| (_joinMuted != data.is_join_muted())
|| (_canChangeJoinMuted != data.is_can_change_join_muted());
|| (_canChangeJoinMuted != data.is_can_change_join_muted())
|| (_title.current() != title);
if (!force && !changed) {
return;
} else if (!force && _version > data.vversion().v) {
@ -189,6 +191,7 @@ void GroupCall::applyCall(const MTPGroupCall &call, bool force) {
_canChangeJoinMuted = data.is_can_change_join_muted();
_version = data.vversion().v;
_fullCount = data.vparticipants_count().v;
_title = title;
changePeerEmptyCallFlag();
}, [&](const MTPDgroupCallDiscarded &data) {
const auto id = _id;

View File

@ -28,6 +28,15 @@ public:
[[nodiscard]] uint64 id() const;
[[nodiscard]] not_null<PeerData*> peer() const;
[[nodiscard]] MTPInputGroupCall input() const;
[[nodiscard]] QString title() const {
return _title.current();
}
[[nodiscard]] rpl::producer<QString> titleValue() const {
return _title.value();
}
void setTitle(const QString &title) {
_title = title;
}
void setPeer(not_null<PeerData*> peer);
@ -105,6 +114,7 @@ private:
int _version = 0;
mtpRequestId _participantsRequestId = 0;
mtpRequestId _reloadRequestId = 0;
rpl::variable<QString> _title;
std::vector<Participant> _participants;
base::flat_map<uint32, not_null<PeerData*>> _participantPeerBySsrc;