mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 23:27:09 +02:00
Added list of active group calls to Calls box.
This commit is contained in:
parent
cd032f5c16
commit
37454b4ff4
5 changed files with 248 additions and 1 deletions
|
@ -2694,6 +2694,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_call_box_clear_all" = "Clear All";
|
||||
"lng_call_box_clear_sure" = "Are you sure you want to completely clear your calls log?";
|
||||
"lng_call_box_clear_button" = "Clear";
|
||||
"lng_call_box_groupcalls_subtitle" = "Active video chats";
|
||||
|
||||
"lng_call_outgoing" = "Outgoing call";
|
||||
"lng_call_video_outgoing" = "Outgoing video call";
|
||||
|
|
|
@ -369,6 +369,10 @@ callCameraReDial: IconButton(callReDial) {
|
|||
icon: icon {{ "calls/call_camera_active", menuIconFg }};
|
||||
iconOver: icon {{ "calls/call_camera_active", menuIconFgOver }};
|
||||
}
|
||||
callGroupCall: IconButton(callCameraReDial) {
|
||||
icon: icon {{ "top_bar_group_call", menuIconFg }};
|
||||
iconOver: icon {{ "top_bar_group_call", menuIconFgOver }};
|
||||
}
|
||||
|
||||
callRatingPadding: margins(24px, 12px, 24px, 0px);
|
||||
callRatingStar: IconButton {
|
||||
|
|
|
@ -25,6 +25,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_changes.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_peer_values.h" // Data::ChannelHasActiveCall.
|
||||
#include "data/data_group_call.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "boxes/delete_messages_box.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "api/api_updates.h"
|
||||
|
@ -40,8 +43,201 @@ namespace {
|
|||
constexpr auto kFirstPageCount = 20;
|
||||
constexpr auto kPerPageCount = 100;
|
||||
|
||||
class GroupCallRow final : public PeerListRow {
|
||||
public:
|
||||
GroupCallRow(not_null<PeerData*> peer);
|
||||
|
||||
void rightActionAddRipple(
|
||||
QPoint point,
|
||||
Fn<void()> updateCallback) override;
|
||||
void rightActionStopLastRipple() override;
|
||||
|
||||
int paintNameIconGetWidth(
|
||||
Painter &p,
|
||||
Fn<void()> repaint,
|
||||
crl::time now,
|
||||
int nameLeft,
|
||||
int nameTop,
|
||||
int nameWidth,
|
||||
int availableWidth,
|
||||
int outerWidth,
|
||||
bool selected) override {
|
||||
return 0;
|
||||
}
|
||||
QSize rightActionSize() const override {
|
||||
return peer()->isChannel() ? QSize(_st.width, _st.height) : QSize();
|
||||
}
|
||||
QMargins rightActionMargins() const override {
|
||||
return QMargins(
|
||||
0,
|
||||
0,
|
||||
st::defaultPeerListItem.photoPosition.x(),
|
||||
0);
|
||||
}
|
||||
void rightActionPaint(
|
||||
Painter &p,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
bool selected,
|
||||
bool actionSelected) override;
|
||||
|
||||
private:
|
||||
const style::IconButton &_st;
|
||||
std::unique_ptr<Ui::RippleAnimation> _actionRipple;
|
||||
|
||||
};
|
||||
|
||||
GroupCallRow::GroupCallRow(not_null<PeerData*> peer)
|
||||
: PeerListRow(peer)
|
||||
, _st(st::callGroupCall) {
|
||||
if (const auto channel = peer->asChannel()) {
|
||||
const auto status = (channel->isMegagroup()
|
||||
? (channel->isPublic()
|
||||
? tr::lng_create_public_channel_title
|
||||
: tr::lng_create_private_channel_title)
|
||||
: (channel->isPublic()
|
||||
? tr::lng_create_public_group_title
|
||||
: tr::lng_create_private_group_title))(tr::now);
|
||||
setCustomStatus(status.toLower());
|
||||
}
|
||||
}
|
||||
|
||||
void GroupCallRow::rightActionPaint(
|
||||
Painter &p,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
bool selected,
|
||||
bool actionSelected) {
|
||||
auto size = rightActionSize();
|
||||
if (_actionRipple) {
|
||||
_actionRipple->paint(
|
||||
p,
|
||||
x + _st.rippleAreaPosition.x(),
|
||||
y + _st.rippleAreaPosition.y(),
|
||||
outerWidth);
|
||||
if (_actionRipple->empty()) {
|
||||
_actionRipple.reset();
|
||||
}
|
||||
}
|
||||
_st.icon.paintInCenter(
|
||||
p,
|
||||
style::rtlrect(x, y, size.width(), size.height(), outerWidth));
|
||||
}
|
||||
|
||||
void GroupCallRow::rightActionAddRipple(
|
||||
QPoint point,
|
||||
Fn<void()> updateCallback) {
|
||||
if (!_actionRipple) {
|
||||
auto mask = Ui::RippleAnimation::EllipseMask(
|
||||
QSize(_st.rippleAreaSize, _st.rippleAreaSize));
|
||||
_actionRipple = std::make_unique<Ui::RippleAnimation>(
|
||||
_st.ripple,
|
||||
std::move(mask),
|
||||
std::move(updateCallback));
|
||||
}
|
||||
_actionRipple->add(point - _st.rippleAreaPosition);
|
||||
}
|
||||
|
||||
void GroupCallRow::rightActionStopLastRipple() {
|
||||
if (_actionRipple) {
|
||||
_actionRipple->lastStop();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace GroupCalls {
|
||||
|
||||
ListController::ListController(not_null<Window::SessionController*> window)
|
||||
: _window(window) {
|
||||
setStyleOverrides(&st::peerListSingleRow);
|
||||
}
|
||||
|
||||
Main::Session &ListController::session() const {
|
||||
return _window->session();
|
||||
}
|
||||
|
||||
void ListController::prepare() {
|
||||
const auto removeRow = [=](not_null<PeerData*> peer) {
|
||||
const auto it = _groupCalls.find(peer->id);
|
||||
if (it != end(_groupCalls)) {
|
||||
const auto &row = it->second;
|
||||
delegate()->peerListRemoveRow(row);
|
||||
_groupCalls.erase(it);
|
||||
}
|
||||
};
|
||||
const auto createRow = [=](not_null<PeerData*> peer) {
|
||||
const auto it = _groupCalls.find(peer->id);
|
||||
if (it == end(_groupCalls)) {
|
||||
auto row = std::make_unique<GroupCallRow>(peer);
|
||||
_groupCalls.emplace(peer->id, row.get());
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
}
|
||||
};
|
||||
|
||||
const auto processPeer = [=](PeerData *peer) {
|
||||
if (!peer) {
|
||||
return;
|
||||
}
|
||||
const auto channel = peer->asChannel();
|
||||
if (channel && Data::ChannelHasActiveCall(channel)) {
|
||||
createRow(peer);
|
||||
} else {
|
||||
removeRow(peer);
|
||||
}
|
||||
};
|
||||
const auto finishProcess = [=] {
|
||||
delegate()->peerListRefreshRows();
|
||||
_fullCount = delegate()->peerListFullRowsCount();
|
||||
};
|
||||
|
||||
session().changes().peerUpdates(
|
||||
Data::PeerUpdate::Flag::GroupCall
|
||||
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
||||
processPeer(update.peer);
|
||||
finishProcess();
|
||||
}, lifetime());
|
||||
|
||||
{
|
||||
auto count = 0;
|
||||
const auto list = session().data().chatsList(nullptr);
|
||||
for (const auto &key : list->pinned()->order()) {
|
||||
processPeer(key.peer());
|
||||
}
|
||||
for (const auto &key : list->indexed()->all()) {
|
||||
if (count > kFirstPageCount) {
|
||||
break;
|
||||
}
|
||||
processPeer(key->key().peer());
|
||||
count++;
|
||||
}
|
||||
finishProcess();
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<bool> ListController::shownValue() const {
|
||||
return _fullCount.value(
|
||||
) | rpl::map(rpl::mappers::_1 > 0) | rpl::distinct_until_changed();
|
||||
}
|
||||
|
||||
void ListController::rowClicked(not_null<PeerListRow*> row) {
|
||||
const auto window = _window;
|
||||
const auto peer = row->peer();
|
||||
crl::on_main(window, [=, peer = row->peer()] {
|
||||
window->showPeerHistory(
|
||||
peer,
|
||||
Window::SectionShow::Way::ClearStack);
|
||||
});
|
||||
}
|
||||
|
||||
void ListController::rowRightActionClicked(not_null<PeerListRow*> row) {
|
||||
_window->startOrJoinGroupCall(row->peer());
|
||||
}
|
||||
|
||||
} // namespace GroupCalls
|
||||
|
||||
class BoxController::Row : public PeerListRow {
|
||||
public:
|
||||
Row(not_null<HistoryItem*> item);
|
||||
|
|
|
@ -15,6 +15,27 @@ class SessionController;
|
|||
} // namespace Window
|
||||
|
||||
namespace Calls {
|
||||
namespace GroupCalls {
|
||||
|
||||
class ListController : public PeerListController {
|
||||
public:
|
||||
explicit ListController(not_null<Window::SessionController*> window);
|
||||
|
||||
[[nodiscard]] rpl::producer<bool> shownValue() const;
|
||||
|
||||
Main::Session &session() const override;
|
||||
void prepare() override;
|
||||
void rowClicked(not_null<PeerListRow*> row) override;
|
||||
void rowRightActionClicked(not_null<PeerListRow*> row) override;
|
||||
|
||||
private:
|
||||
const not_null<Window::SessionController*> _window;
|
||||
base::flat_map<PeerId, not_null<PeerListRow*>> _groupCalls;
|
||||
rpl::variable<int> _fullCount;
|
||||
|
||||
};
|
||||
|
||||
} // namespace GroupCalls
|
||||
|
||||
class BoxController : public PeerListController {
|
||||
public:
|
||||
|
@ -34,6 +55,7 @@ private:
|
|||
void receivedCalls(const QVector<MTPMessage> &result);
|
||||
void refreshAbout();
|
||||
|
||||
class GroupCallRow;
|
||||
class Row;
|
||||
Row *rowForItem(not_null<const HistoryItem*> item);
|
||||
|
||||
|
|
|
@ -96,16 +96,40 @@ constexpr auto kPlayStatusLimit = 2;
|
|||
void ShowCallsBox(not_null<Window::SessionController*> window) {
|
||||
struct State {
|
||||
State(not_null<Window::SessionController*> window)
|
||||
: callsController(window) {
|
||||
: callsController(window)
|
||||
, groupCallsController(window) {
|
||||
}
|
||||
Calls::BoxController callsController;
|
||||
PeerListContentDelegateSimple callsDelegate;
|
||||
|
||||
Calls::GroupCalls::ListController groupCallsController;
|
||||
PeerListContentDelegateSimple groupCallsDelegate;
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> menu;
|
||||
};
|
||||
|
||||
window->show(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
const auto state = box->lifetime().make_state<State>(window);
|
||||
|
||||
const auto groupCalls = box->addRow(
|
||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
box,
|
||||
object_ptr<Ui::VerticalLayout>(box)),
|
||||
{});
|
||||
groupCalls->hide(anim::type::instant);
|
||||
groupCalls->toggleOn(state->groupCallsController.shownValue());
|
||||
|
||||
Settings::AddSubsectionTitle(
|
||||
groupCalls->entity(),
|
||||
tr::lng_call_box_groupcalls_subtitle());
|
||||
state->groupCallsDelegate.setContent(groupCalls->entity()->add(
|
||||
object_ptr<PeerListContent>(box, &state->groupCallsController),
|
||||
{}));
|
||||
state->groupCallsController.setDelegate(&state->groupCallsDelegate);
|
||||
Settings::AddSkip(groupCalls->entity());
|
||||
Settings::AddDivider(groupCalls->entity());
|
||||
Settings::AddSkip(groupCalls->entity());
|
||||
|
||||
const auto content = box->addRow(
|
||||
object_ptr<PeerListContent>(box, &state->callsController),
|
||||
{});
|
||||
|
|
Loading…
Add table
Reference in a new issue