mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-03 21:54:05 +02:00
Render confcall messages as phone calls.
This commit is contained in:
parent
be611c1920
commit
346f7aadd6
13 changed files with 137 additions and 127 deletions
|
@ -2220,10 +2220,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_action_message_price_paid#other" = "Messages now cost {count} Stars each in this group.";
|
||||
"lng_you_paid_stars#one" = "You paid {count} Star.";
|
||||
"lng_you_paid_stars#other" = "You paid {count} Stars.";
|
||||
"lng_action_confcall_invitation" = "Call invitation...";
|
||||
"lng_action_confcall_missed" = "Missed conference call";
|
||||
"lng_action_confcall_ongoing" = "Ongoing conference call";
|
||||
"lng_action_confcall_finished" = "Conference call";
|
||||
|
||||
"lng_you_joined_group" = "You joined this group";
|
||||
|
||||
|
@ -4684,6 +4680,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_call_video_declined" = "Declined video call";
|
||||
"lng_call_duration_info" = "{time}, {duration}";
|
||||
"lng_call_type_and_duration" = "{type} ({duration})";
|
||||
"lng_call_invitation" = "Call invitation";
|
||||
"lng_call_ongoing" = "Ongoing call";
|
||||
|
||||
"lng_call_rate_label" = "Please rate the quality of your call";
|
||||
"lng_call_rate_comment" = "Comment (optional)";
|
||||
|
|
|
@ -430,9 +430,9 @@ BoxController::Row::Type BoxController::Row::ComputeType(
|
|||
return Type::Out;
|
||||
} else if (auto media = item->media()) {
|
||||
if (const auto call = media->call()) {
|
||||
const auto reason = call->finishReason;
|
||||
if (reason == Data::Call::FinishReason::Busy
|
||||
|| reason == Data::Call::FinishReason::Missed) {
|
||||
using State = Data::CallState;
|
||||
const auto state = call->state;
|
||||
if (state == State::Busy || state == State::Missed) {
|
||||
return Type::Missed;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,7 +236,6 @@ void Instance::startOrJoinConferenceCall(StartConferenceCallArgs args) {
|
|||
args.migrating ? args.linkSlug : QString());
|
||||
|
||||
const auto session = &args.call->peer()->session();
|
||||
const auto showShareLink = args.migrating && args.invite.empty();
|
||||
auto call = std::make_unique<GroupCall>(
|
||||
_delegate.get(),
|
||||
Calls::Group::ConferenceInfo{
|
||||
|
|
|
@ -457,28 +457,42 @@ Invoice ComputeInvoiceData(
|
|||
|
||||
Call ComputeCallData(const MTPDmessageActionPhoneCall &call) {
|
||||
auto result = Call();
|
||||
result.finishReason = [&] {
|
||||
result.state = [&] {
|
||||
if (const auto reason = call.vreason()) {
|
||||
return reason->match([](const MTPDphoneCallDiscardReasonBusy &) {
|
||||
return CallFinishReason::Busy;
|
||||
return CallState::Busy;
|
||||
}, [](const MTPDphoneCallDiscardReasonDisconnect &) {
|
||||
return CallFinishReason::Disconnected;
|
||||
return CallState::Disconnected;
|
||||
}, [](const MTPDphoneCallDiscardReasonHangup &) {
|
||||
return CallFinishReason::Hangup;
|
||||
return CallState::Hangup;
|
||||
}, [](const MTPDphoneCallDiscardReasonMissed &) {
|
||||
return CallFinishReason::Missed;
|
||||
return CallState::Missed;
|
||||
}, [](const MTPDphoneCallDiscardReasonMigrateConferenceCall &) {
|
||||
return CallFinishReason::MigrateConferenceCall;
|
||||
return CallState::MigrateConferenceCall;
|
||||
});
|
||||
Unexpected("Call reason type.");
|
||||
}
|
||||
return CallFinishReason::Hangup;
|
||||
return CallState::Hangup;
|
||||
}();
|
||||
result.duration = call.vduration().value_or_empty();
|
||||
result.video = call.is_video();
|
||||
return result;
|
||||
}
|
||||
|
||||
Call ComputeCallData(const MTPDmessageActionConferenceCall &call) {
|
||||
return {
|
||||
.conferenceId = call.vcall_id().v,
|
||||
.duration = call.vduration().value_or_empty(),
|
||||
.state = (call.vduration().value_or_empty()
|
||||
? CallState::Hangup
|
||||
: call.is_missed()
|
||||
? CallState::Missed
|
||||
: call.is_active()
|
||||
? CallState::Active
|
||||
: CallState::Invitation),
|
||||
};
|
||||
}
|
||||
|
||||
GiveawayStart ComputeGiveawayStartData(
|
||||
not_null<HistoryItem*> item,
|
||||
const MTPDmessageMediaGiveaway &data) {
|
||||
|
@ -1686,7 +1700,7 @@ const Call *MediaCall::call() const {
|
|||
}
|
||||
|
||||
TextWithEntities MediaCall::notificationText() const {
|
||||
auto result = Text(parent(), _call.finishReason, _call.video);
|
||||
auto result = Text(parent(), _call.state, _call.video);
|
||||
if (_call.duration > 0) {
|
||||
result = tr::lng_call_type_and_duration(
|
||||
tr::now,
|
||||
|
@ -1727,21 +1741,25 @@ std::unique_ptr<HistoryView::Media> MediaCall::createView(
|
|||
|
||||
QString MediaCall::Text(
|
||||
not_null<HistoryItem*> item,
|
||||
CallFinishReason reason,
|
||||
CallState state,
|
||||
bool video) {
|
||||
if (item->out()) {
|
||||
return ((reason == CallFinishReason::Missed)
|
||||
if (state == CallState::Invitation) {
|
||||
return tr::lng_call_invitation(tr::now);
|
||||
} else if (state == CallState::Active) {
|
||||
return tr::lng_call_ongoing(tr::now);
|
||||
} else if (item->out()) {
|
||||
return ((state == CallState::Missed)
|
||||
? (video
|
||||
? tr::lng_call_video_cancelled
|
||||
: tr::lng_call_cancelled)
|
||||
: (video
|
||||
? tr::lng_call_video_outgoing
|
||||
: tr::lng_call_outgoing))(tr::now);
|
||||
} else if (reason == CallFinishReason::Missed) {
|
||||
} else if (state == CallState::Missed) {
|
||||
return (video
|
||||
? tr::lng_call_video_missed
|
||||
: tr::lng_call_missed)(tr::now);
|
||||
} else if (reason == CallFinishReason::Busy) {
|
||||
} else if (state == CallState::Busy) {
|
||||
return (video
|
||||
? tr::lng_call_video_declined
|
||||
: tr::lng_call_declined)(tr::now);
|
||||
|
|
|
@ -41,12 +41,14 @@ class WallPaper;
|
|||
class Session;
|
||||
struct UniqueGift;
|
||||
|
||||
enum class CallFinishReason : char {
|
||||
enum class CallState : char {
|
||||
Missed,
|
||||
Busy,
|
||||
Disconnected,
|
||||
Hangup,
|
||||
MigrateConferenceCall,
|
||||
Invitation,
|
||||
Active,
|
||||
};
|
||||
|
||||
struct SharedContact final {
|
||||
|
@ -78,10 +80,11 @@ struct SharedContact final {
|
|||
};
|
||||
|
||||
struct Call {
|
||||
using FinishReason = CallFinishReason;
|
||||
using State = CallState;
|
||||
|
||||
CallId conferenceId = 0;
|
||||
int duration = 0;
|
||||
FinishReason finishReason = FinishReason::Missed;
|
||||
State state = State::Missed;
|
||||
bool video = false;
|
||||
|
||||
};
|
||||
|
@ -462,9 +465,9 @@ public:
|
|||
not_null<HistoryItem*> realParent,
|
||||
HistoryView::Element *replacing = nullptr) override;
|
||||
|
||||
static QString Text(
|
||||
[[nodiscard]] static QString Text(
|
||||
not_null<HistoryItem*> item,
|
||||
CallFinishReason reason,
|
||||
CallState state,
|
||||
bool video);
|
||||
|
||||
private:
|
||||
|
@ -799,6 +802,8 @@ private:
|
|||
const MTPDmessageMediaPaidMedia &data);
|
||||
|
||||
[[nodiscard]] Call ComputeCallData(const MTPDmessageActionPhoneCall &call);
|
||||
[[nodiscard]] Call ComputeCallData(
|
||||
const MTPDmessageActionConferenceCall &call);
|
||||
|
||||
[[nodiscard]] GiveawayStart ComputeGiveawayStartData(
|
||||
not_null<HistoryItem*> item,
|
||||
|
|
|
@ -1461,18 +1461,18 @@ ServiceAction ParseServiceAction(
|
|||
content.duration = duration->v;
|
||||
}
|
||||
if (const auto reason = data.vreason()) {
|
||||
using Reason = ActionPhoneCall::DiscardReason;
|
||||
content.discardReason = reason->match(
|
||||
using State = ActionPhoneCall::State;
|
||||
content.state = reason->match(
|
||||
[](const MTPDphoneCallDiscardReasonMissed &data) {
|
||||
return Reason::Missed;
|
||||
return State::Missed;
|
||||
}, [](const MTPDphoneCallDiscardReasonDisconnect &data) {
|
||||
return Reason::Disconnect;
|
||||
return State::Disconnect;
|
||||
}, [](const MTPDphoneCallDiscardReasonHangup &data) {
|
||||
return Reason::Hangup;
|
||||
return State::Hangup;
|
||||
}, [](const MTPDphoneCallDiscardReasonBusy &data) {
|
||||
return Reason::Busy;
|
||||
return State::Busy;
|
||||
}, [](const MTPDphoneCallDiscardReasonMigrateConferenceCall &) {
|
||||
return Reason::MigrateConferenceCall;
|
||||
return State::MigrateConferenceCall;
|
||||
});
|
||||
}
|
||||
result.content = content;
|
||||
|
@ -1714,11 +1714,20 @@ ServiceAction ParseServiceAction(
|
|||
.stars = int(data.vstars().v),
|
||||
};
|
||||
}, [&](const MTPDmessageActionConferenceCall &data) {
|
||||
result.content = ActionConferenceCall{
|
||||
.duration = data.vduration().value_or_empty(),
|
||||
.active = data.is_active(),
|
||||
.missed = data.is_missed(),
|
||||
};
|
||||
auto content = ActionPhoneCall();
|
||||
using State = ActionPhoneCall::State;
|
||||
content.conferenceId = data.vcall_id().v;
|
||||
if (const auto duration = data.vduration()) {
|
||||
content.duration = duration->v;
|
||||
}
|
||||
content.state = data.is_missed()
|
||||
? State::Missed
|
||||
: data.is_active()
|
||||
? State::Active
|
||||
: data.vduration().value_or_empty()
|
||||
? State::Hangup
|
||||
: State::Invitation;
|
||||
result.content = content;
|
||||
}, [](const MTPDmessageActionEmpty &data) {});
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -497,15 +497,19 @@ struct ActionPaymentSent {
|
|||
};
|
||||
|
||||
struct ActionPhoneCall {
|
||||
enum class DiscardReason {
|
||||
enum class State {
|
||||
Unknown,
|
||||
Missed,
|
||||
Disconnect,
|
||||
Hangup,
|
||||
Busy,
|
||||
MigrateConferenceCall,
|
||||
Invitation,
|
||||
Active,
|
||||
};
|
||||
DiscardReason discardReason = DiscardReason::Unknown;
|
||||
|
||||
uint64 conferenceId = 0;
|
||||
State state = State::Unknown;
|
||||
int duration = 0;
|
||||
};
|
||||
|
||||
|
@ -671,12 +675,6 @@ struct ActionPaidMessagesPrice {
|
|||
int stars = 0;
|
||||
};
|
||||
|
||||
struct ActionConferenceCall {
|
||||
int duration = 0;
|
||||
bool active = false;
|
||||
bool missed = false;
|
||||
};
|
||||
|
||||
struct ServiceAction {
|
||||
std::variant<
|
||||
v::null_t,
|
||||
|
@ -724,8 +722,7 @@ struct ServiceAction {
|
|||
ActionPrizeStars,
|
||||
ActionStarGift,
|
||||
ActionPaidMessagesRefunded,
|
||||
ActionPaidMessagesPrice,
|
||||
ActionConferenceCall> content;
|
||||
ActionPaidMessagesPrice> content;
|
||||
};
|
||||
|
||||
ServiceAction ParseServiceAction(
|
||||
|
|
|
@ -408,7 +408,7 @@ Stats AbstractWriter::produceTestExample(
|
|||
auto message = serviceMessage();
|
||||
auto action = Data::ActionPhoneCall();
|
||||
action.duration = counter();
|
||||
action.discardReason = Data::ActionPhoneCall::DiscardReason::Busy;
|
||||
action.state = Data::ActionPhoneCall::State::Busy;
|
||||
message.action.content = action;
|
||||
return message;
|
||||
}());
|
||||
|
|
|
@ -1387,16 +1387,6 @@ auto HtmlWriter::Wrap::pushMessage(
|
|||
+ QString::number(data.stars).toUtf8()
|
||||
+ " Telegram Stars.";
|
||||
return result;
|
||||
}, [&](const ActionConferenceCall &data) {
|
||||
return data.missed
|
||||
? "Missed conference call"
|
||||
: data.active
|
||||
? "Ongoing conference call"
|
||||
: data.duration
|
||||
? "Conference call ("
|
||||
+ NumberToString(data.duration)
|
||||
+ " seconds)"
|
||||
: "Declined conference call";
|
||||
}, [](v::null_t) { return QByteArray(); });
|
||||
|
||||
if (!serviceText.isEmpty()) {
|
||||
|
@ -2286,16 +2276,20 @@ MediaData HtmlWriter::Wrap::prepareMediaData(
|
|||
if (const auto call = std::get_if<ActionPhoneCall>(&action.content)) {
|
||||
result.classes = "media_call";
|
||||
result.title = peers.peer(message.out
|
||||
? message.peerId
|
||||
: message.selfId).name();
|
||||
? message.peerId
|
||||
: message.selfId).name();
|
||||
result.status = [&] {
|
||||
using Reason = ActionPhoneCall::DiscardReason;
|
||||
const auto reason = call->discardReason;
|
||||
if (message.out) {
|
||||
return reason == Reason::Missed ? "Cancelled" : "Outgoing";
|
||||
} else if (reason == Reason::Missed) {
|
||||
using State = ActionPhoneCall::State;
|
||||
const auto state = call->state;
|
||||
if (state == State::Invitation) {
|
||||
return "Invitation";
|
||||
} else if (state == State::Active) {
|
||||
return "Ongoing";
|
||||
} else if (message.out) {
|
||||
return (state == State::Missed) ? "Cancelled" : "Outgoing";
|
||||
} else if (state == State::Missed) {
|
||||
return "Missed";
|
||||
} else if (reason == Reason::Busy) {
|
||||
} else if (state == State::Busy) {
|
||||
return "Declined";
|
||||
}
|
||||
return "Incoming";
|
||||
|
|
|
@ -461,22 +461,27 @@ QByteArray SerializeMessage(
|
|||
}
|
||||
}, [&](const ActionPhoneCall &data) {
|
||||
pushActor();
|
||||
pushAction("phone_call");
|
||||
pushAction(data.conferenceId ? "conference_call" : "phone_call");
|
||||
if (data.duration) {
|
||||
push("duration_seconds", data.duration);
|
||||
}
|
||||
using Reason = ActionPhoneCall::DiscardReason;
|
||||
push("discard_reason", [&] {
|
||||
switch (data.discardReason) {
|
||||
case Reason::Busy: return "busy";
|
||||
case Reason::Disconnect: return "disconnect";
|
||||
case Reason::Hangup: return "hangup";
|
||||
case Reason::Missed: return "missed";
|
||||
case Reason::MigrateConferenceCall:
|
||||
return "migrate_conference_all";
|
||||
}
|
||||
return "";
|
||||
}());
|
||||
using State = ActionPhoneCall::State;
|
||||
if (data.conferenceId) {
|
||||
push("is_active", data.state == State::Active);
|
||||
push("is_missed", data.state == State::Missed);
|
||||
} else {
|
||||
push("discard_reason", [&] {
|
||||
switch (data.state) {
|
||||
case State::Busy: return "busy";
|
||||
case State::Disconnect: return "disconnect";
|
||||
case State::Hangup: return "hangup";
|
||||
case State::Missed: return "missed";
|
||||
case State::MigrateConferenceCall:
|
||||
return "migrate_conference_all";
|
||||
}
|
||||
return "";
|
||||
}());
|
||||
}
|
||||
}, [&](const ActionScreenshotTaken &data) {
|
||||
pushActor();
|
||||
pushAction("take_screenshot");
|
||||
|
@ -674,12 +679,6 @@ QByteArray SerializeMessage(
|
|||
pushActor();
|
||||
pushAction("paid_messages_price_change");
|
||||
push("price_stars", data.stars);
|
||||
}, [&](const ActionConferenceCall &data) {
|
||||
pushActor();
|
||||
pushAction("conference_call");
|
||||
push("duration_seconds", data.duration);
|
||||
push("is_missed", data.missed);
|
||||
push("is_active", data.active);
|
||||
}, [](v::null_t) {});
|
||||
|
||||
if (v::is_null(message.action.content)) {
|
||||
|
|
|
@ -483,6 +483,12 @@ HistoryItem::HistoryItem(
|
|||
this,
|
||||
Data::ComputeCallData(data));
|
||||
setTextValue({});
|
||||
}, [&](const MTPDmessageActionConferenceCall &data) {
|
||||
createComponents(CreateConfig());
|
||||
_media = std::make_unique<Data::MediaCall>(
|
||||
this,
|
||||
Data::ComputeCallData(data));
|
||||
setTextValue({});
|
||||
}, [&](const auto &) {
|
||||
createServiceFromMtp(data);
|
||||
});
|
||||
|
@ -5624,32 +5630,8 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
|||
return result;
|
||||
};
|
||||
|
||||
auto prepareConferenceCall = [&](const MTPDmessageActionConferenceCall &action) {
|
||||
auto result = PreparedServiceText();
|
||||
const auto duration = action.vduration().value_or_empty();
|
||||
result.text.text = action.is_missed()
|
||||
? tr::lng_action_confcall_missed(tr::now)
|
||||
: action.is_active()
|
||||
? tr::lng_action_confcall_ongoing(tr::now)
|
||||
: duration
|
||||
? tr::lng_action_confcall_finished(tr::now)
|
||||
: tr::lng_action_confcall_invitation(tr::now);
|
||||
|
||||
if (duration) {
|
||||
result.text.text += " (" + QString::number(duration) + " seconds)";
|
||||
}
|
||||
|
||||
const auto id = this->id;
|
||||
setCustomServiceLink(std::make_shared<LambdaClickHandler>([=](
|
||||
ClickContext context) {
|
||||
const auto my = context.other.value<ClickHandlerContext>();
|
||||
const auto weak = my.sessionWindow;
|
||||
if (const auto strong = weak.get()) {
|
||||
strong->resolveConferenceCall(id);
|
||||
}
|
||||
}));
|
||||
|
||||
return result;
|
||||
auto prepareConferenceCall = [&](const MTPDmessageActionConferenceCall &) -> PreparedServiceText {
|
||||
Unexpected("PhoneCall type in setServiceMessageFromMtp.");
|
||||
};
|
||||
|
||||
setServiceText(action.match(
|
||||
|
|
|
@ -17,20 +17,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_element.h"
|
||||
#include "history/view/history_view_cursor_state.h"
|
||||
#include "core/application.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "calls/calls_instance.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "data/data_user.h"
|
||||
#include "main/main_session.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
namespace {
|
||||
|
||||
using FinishReason = Data::CallFinishReason;
|
||||
using State = Data::CallState;
|
||||
|
||||
[[nodiscard]] int ComputeDuration(FinishReason reason, int duration) {
|
||||
return (reason != FinishReason::Missed
|
||||
&& reason != FinishReason::Busy)
|
||||
[[nodiscard]] int ComputeDuration(State state, int duration) {
|
||||
return (state != State::Missed && state != State::Busy)
|
||||
? duration
|
||||
: 0;
|
||||
}
|
||||
|
@ -41,11 +42,12 @@ Call::Call(
|
|||
not_null<Element*> parent,
|
||||
not_null<Data::Call*> call)
|
||||
: Media(parent)
|
||||
, _duration(ComputeDuration(call->finishReason, call->duration))
|
||||
, _reason(call->finishReason)
|
||||
, _duration(ComputeDuration(call->state, call->duration))
|
||||
, _state(call->state)
|
||||
, _conference(call->conferenceId != 0)
|
||||
, _video(call->video) {
|
||||
const auto item = parent->data();
|
||||
_text = Data::MediaCall::Text(item, _reason, _video);
|
||||
_text = Data::MediaCall::Text(item, _state, _video);
|
||||
_status = QLocale().toString(
|
||||
parent->dateTime().time(),
|
||||
QLocale::ShortFormat);
|
||||
|
@ -61,13 +63,20 @@ Call::Call(
|
|||
|
||||
QSize Call::countOptimalSize() {
|
||||
const auto user = _parent->history()->peer->asUser();
|
||||
const auto conference = _conference;
|
||||
const auto video = _video;
|
||||
_link = std::make_shared<LambdaClickHandler>([=] {
|
||||
if (user) {
|
||||
const auto id = _parent->data()->id;
|
||||
_link = std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
||||
if (conference) {
|
||||
const auto my = context.other.value<ClickHandlerContext>();
|
||||
const auto weak = my.sessionWindow;
|
||||
if (const auto strong = weak.get()) {
|
||||
strong->resolveConferenceCall(id);
|
||||
}
|
||||
} else if (user) {
|
||||
Core::App().calls().startOutgoingCall(user, video);
|
||||
}
|
||||
});
|
||||
|
||||
auto maxWidth = st::historyCallWidth;
|
||||
auto minHeight = st::historyCallHeight;
|
||||
if (!isBubbleTop()) {
|
||||
|
@ -96,8 +105,7 @@ void Call::draw(Painter &p, const PaintContext &context) const {
|
|||
p.drawTextLeft(nameleft, nametop, paintw, _text);
|
||||
|
||||
auto statusleft = nameleft;
|
||||
auto missed = (_reason == FinishReason::Missed)
|
||||
|| (_reason == FinishReason::Busy);
|
||||
auto missed = (_state == State::Missed) || (_state == State::Busy);
|
||||
const auto &arrow = missed
|
||||
? stm->historyCallArrowMissed
|
||||
: stm->historyCallArrow;
|
||||
|
|
|
@ -10,7 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/media/history_view_media.h"
|
||||
|
||||
namespace Data {
|
||||
enum class CallFinishReason : char;
|
||||
enum class CallState : char;
|
||||
struct Call;
|
||||
} // namespace Data
|
||||
|
||||
|
@ -40,12 +40,13 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
using FinishReason = Data::CallFinishReason;
|
||||
using State = Data::CallState;
|
||||
|
||||
QSize countOptimalSize() override;
|
||||
|
||||
const int _duration = 0;
|
||||
const FinishReason _reason;
|
||||
const State _state = {};
|
||||
const bool _conference = false;
|
||||
const bool _video = false;
|
||||
|
||||
QString _text;
|
||||
|
|
Loading…
Add table
Reference in a new issue