mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-08-06 03:42:56 +00:00
1179 lines
31 KiB
C++
1179 lines
31 KiB
C++
/*
|
|
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 "history/history_inner_widget_accessibility.h"
|
|
|
|
#include "base/unixtime.h"
|
|
#include "data/data_document.h"
|
|
#include "data/data_game.h"
|
|
#include "data/data_media_types.h"
|
|
#include "data/data_message_reaction_id.h"
|
|
#include "data/data_photo.h"
|
|
#include "data/data_poll.h"
|
|
#include "data/data_session.h"
|
|
#include "data/data_todo_list.h"
|
|
#include "data/data_user.h"
|
|
#include "data/data_web_page.h"
|
|
#include "history/view/history_view_element.h"
|
|
#include "history/history.h"
|
|
#include "history/history_item.h"
|
|
#include "history/history_item_components.h"
|
|
#include "lang/lang_keys.h"
|
|
#include "ui/text/format_values.h"
|
|
|
|
namespace HistoryView {
|
|
|
|
QString MessageAccessibilityName(
|
|
not_null<const Element*> view,
|
|
not_null<History*> history) {
|
|
const auto item = view->data();
|
|
|
|
if (item->isService()) {
|
|
const auto text = item->notificationText().text;
|
|
return text.isEmpty() ? QString() : text;
|
|
}
|
|
|
|
QStringList lines;
|
|
|
|
if (item->out()) {
|
|
lines.push_back(item->unread(history)
|
|
? tr::lng_sr_message_not_seen(tr::now)
|
|
: tr::lng_sr_message_seen(tr::now));
|
|
}
|
|
|
|
if (item->out()) {
|
|
lines.push_back(tr::lng_sr_from_me(tr::now));
|
|
} else if (const auto from = item->displayFrom()) {
|
|
lines.push_back(from->name());
|
|
}
|
|
|
|
if (const auto bot = item->viaBot()) {
|
|
lines.push_back(tr::lng_inline_bot_via(
|
|
tr::now,
|
|
lt_inline_bot,
|
|
'@' + bot->username()));
|
|
}
|
|
|
|
if (const auto reply = item->Get<HistoryMessageReply>()) {
|
|
if (const auto message = reply->resolvedMessage.get()) {
|
|
const auto replyFrom = message->displayFrom();
|
|
const auto replyName = replyFrom
|
|
? replyFrom->name()
|
|
: QString();
|
|
const auto replyText = message->inReplyText().text;
|
|
if (!replyName.isEmpty() || !replyText.isEmpty()) {
|
|
lines.push_back(tr::lng_sr_message_reply_to(
|
|
tr::now,
|
|
lt_name,
|
|
replyName.isEmpty()
|
|
? tr::lng_sr_from_me(tr::now)
|
|
: replyName,
|
|
lt_text,
|
|
replyText));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
|
if (forwarded->originalSender) {
|
|
lines.push_back(tr::lng_forwarded(
|
|
tr::now,
|
|
lt_user,
|
|
forwarded->originalSender->name()));
|
|
} else if (forwarded->originalHiddenSenderInfo) {
|
|
lines.push_back(tr::lng_forwarded(
|
|
tr::now,
|
|
lt_user,
|
|
forwarded->originalHiddenSenderInfo->name));
|
|
}
|
|
}
|
|
|
|
if (const auto media = item->media()) {
|
|
QStringList mediaParts;
|
|
if (const auto document = media->document()) {
|
|
if (document->isVoiceMessage()) {
|
|
mediaParts.push_back(tr::lng_in_dlg_audio(tr::now));
|
|
} else if (document->isVideoMessage()) {
|
|
mediaParts.push_back(tr::lng_in_dlg_video_message(tr::now));
|
|
} else if (document->isSong()) {
|
|
mediaParts.push_back(tr::lng_in_dlg_audio_file(tr::now));
|
|
} else if (document->isVideoFile()) {
|
|
mediaParts.push_back(tr::lng_in_dlg_video(tr::now));
|
|
} else if (document->isAnimation()) {
|
|
mediaParts.push_back(u"GIF"_q);
|
|
} else if (const auto sticker = document->sticker()) {
|
|
mediaParts.push_back(tr::lng_in_dlg_sticker(tr::now));
|
|
if (!sticker->alt.isEmpty()) {
|
|
mediaParts.push_back(sticker->alt);
|
|
}
|
|
} else {
|
|
mediaParts.push_back(tr::lng_in_dlg_file(tr::now));
|
|
}
|
|
if (document->loading()) {
|
|
mediaParts.push_back(
|
|
tr::lng_sr_message_downloading(tr::now));
|
|
} else if (!document->filepath(true).isEmpty()
|
|
|| document->loadedInMediaCache()) {
|
|
mediaParts.push_back(
|
|
tr::lng_emoji_set_ready(tr::now));
|
|
} else {
|
|
mediaParts.push_back(
|
|
tr::lng_sr_message_not_downloaded(tr::now));
|
|
}
|
|
if (document->isVoiceMessage()
|
|
|| document->isVideoMessage()) {
|
|
mediaParts.push_back(item->isUnreadMedia()
|
|
? tr::lng_sr_message_not_played(tr::now)
|
|
: tr::lng_sr_message_played(tr::now));
|
|
}
|
|
if (const auto song = document->song()) {
|
|
if (!song->performer.isEmpty()) {
|
|
mediaParts.push_back(song->performer);
|
|
}
|
|
if (!song->title.isEmpty()) {
|
|
mediaParts.push_back(song->title);
|
|
}
|
|
}
|
|
if (!document->isSong()
|
|
&& !document->isVoiceMessage()
|
|
&& !document->isVideoMessage()
|
|
&& !document->sticker()) {
|
|
const auto name = document->filename();
|
|
if (!name.isEmpty()) {
|
|
mediaParts.push_back(name);
|
|
}
|
|
}
|
|
const auto duration = document->duration();
|
|
if (duration > 0) {
|
|
mediaParts.push_back(
|
|
Ui::FormatDurationText(duration / 1000));
|
|
}
|
|
if (!document->dimensions.isEmpty()
|
|
&& (document->isVideoFile()
|
|
|| document->isImage())) {
|
|
mediaParts.push_back(
|
|
Ui::FormatImageSizeText(document->dimensions));
|
|
}
|
|
if (document->size > 0) {
|
|
mediaParts.push_back(
|
|
Ui::FormatSizeText(document->size));
|
|
}
|
|
} else if (const auto photo = media->photo()) {
|
|
mediaParts.push_back(tr::lng_in_dlg_photo(tr::now));
|
|
if (media->hasSpoiler()) {
|
|
mediaParts.push_back(
|
|
tr::lng_sr_message_spoiler(tr::now));
|
|
}
|
|
const auto large = photo->size(
|
|
Data::PhotoSize::Large);
|
|
if (large && !large->isEmpty()) {
|
|
mediaParts.push_back(
|
|
Ui::FormatImageSizeText(*large));
|
|
}
|
|
} else if (const auto call = media->call()) {
|
|
const auto notification = item->notificationText().text;
|
|
if (!notification.isEmpty()) {
|
|
mediaParts.push_back(notification);
|
|
}
|
|
if (call->duration > 0) {
|
|
mediaParts.push_back(
|
|
Ui::FormatDurationText(call->duration));
|
|
}
|
|
} else if (const auto poll = media->poll()) {
|
|
mediaParts.push_back(poll->quiz()
|
|
? tr::lng_polls_public_quiz(tr::now)
|
|
: tr::lng_polls_public(tr::now));
|
|
if (!poll->question.text.isEmpty()) {
|
|
mediaParts.push_back(poll->question.text);
|
|
}
|
|
if (poll->closed()) {
|
|
mediaParts.push_back(
|
|
tr::lng_hours_closed(tr::now));
|
|
}
|
|
mediaParts.push_back(tr::lng_polls_votes_count(
|
|
tr::now,
|
|
lt_count,
|
|
poll->totalVoters));
|
|
} else if (const auto contact = media->sharedContact()) {
|
|
auto contactName = contact->firstName;
|
|
if (!contact->lastName.isEmpty()) {
|
|
if (!contactName.isEmpty()) {
|
|
contactName += u" "_q;
|
|
}
|
|
contactName += contact->lastName;
|
|
}
|
|
if (!contactName.isEmpty()) {
|
|
mediaParts.push_back(contactName);
|
|
}
|
|
if (!contact->phoneNumber.isEmpty()) {
|
|
mediaParts.push_back(contact->phoneNumber);
|
|
}
|
|
} else if (media->location()) {
|
|
mediaParts.push_back(item->notificationText().text);
|
|
} else if (const auto game = media->game()) {
|
|
if (!game->title.isEmpty()) {
|
|
mediaParts.push_back(game->title);
|
|
}
|
|
} else if (const auto invoice = media->invoice()) {
|
|
if (!invoice->title.isEmpty()) {
|
|
mediaParts.push_back(invoice->title);
|
|
}
|
|
mediaParts.push_back(invoice->currency
|
|
+ u" "_q
|
|
+ QString::number(invoice->amount / 100.0, 'f', 2));
|
|
} else if (const auto gift = media->gift()) {
|
|
switch (gift->type) {
|
|
case Data::GiftType::Premium:
|
|
mediaParts.push_back(
|
|
tr::lng_sr_message_gift_premium(
|
|
tr::now,
|
|
lt_count,
|
|
gift->count));
|
|
break;
|
|
case Data::GiftType::Credits:
|
|
case Data::GiftType::StarGift:
|
|
mediaParts.push_back(
|
|
tr::lng_sr_message_gift_credits(
|
|
tr::now,
|
|
lt_count,
|
|
gift->count));
|
|
break;
|
|
default:
|
|
if (!gift->giftTitle.isEmpty()) {
|
|
mediaParts.push_back(gift->giftTitle);
|
|
}
|
|
break;
|
|
}
|
|
} else if (const auto todolist = media->todolist()) {
|
|
if (!todolist->title.text.isEmpty()) {
|
|
mediaParts.push_back(todolist->title.text);
|
|
}
|
|
} else if (media->giveawayStart() || media->giveawayResults()) {
|
|
mediaParts.push_back(item->notificationText().text);
|
|
} else {
|
|
const auto notification = item->notificationText().text;
|
|
if (!notification.isEmpty()) {
|
|
mediaParts.push_back(notification);
|
|
}
|
|
}
|
|
if (!mediaParts.isEmpty()) {
|
|
lines.push_back(mediaParts.join(u", "_q));
|
|
}
|
|
if (const auto webpage = media->webpage()) {
|
|
QStringList webParts;
|
|
if (!webpage->siteName.isEmpty()) {
|
|
webParts.push_back(webpage->siteName);
|
|
}
|
|
if (!webpage->title.isEmpty()) {
|
|
webParts.push_back(webpage->title);
|
|
}
|
|
if (!webpage->description.text.isEmpty()) {
|
|
webParts.push_back(webpage->description.text);
|
|
}
|
|
if (!webParts.isEmpty()) {
|
|
lines.push_back(webParts.join(u": "_q));
|
|
}
|
|
}
|
|
const auto &caption = item->originalText().text;
|
|
if (!caption.isEmpty()) {
|
|
lines.push_back(caption);
|
|
}
|
|
} else {
|
|
const auto &text = item->originalText().text;
|
|
if (!text.isEmpty()) {
|
|
lines.push_back(text);
|
|
}
|
|
}
|
|
|
|
const auto factcheck = item->factcheckText();
|
|
if (!factcheck.empty()) {
|
|
lines.push_back(factcheck.text);
|
|
}
|
|
|
|
if (item->isPinned()) {
|
|
lines.push_back(tr::lng_sr_chat_pinned(tr::now));
|
|
}
|
|
|
|
QStringList statusParts;
|
|
if (item->out()) {
|
|
if (item->isSending()) {
|
|
statusParts.push_back(tr::lng_sr_chat_sending(tr::now));
|
|
} else if (item->hasFailed()) {
|
|
statusParts.push_back(tr::lng_sr_chat_failed(tr::now));
|
|
} else {
|
|
statusParts.push_back(tr::lng_sr_chat_sent(tr::now));
|
|
}
|
|
} else {
|
|
statusParts.push_back(tr::lng_sr_chat_received(tr::now));
|
|
}
|
|
if (item->Has<HistoryMessageEdited>()) {
|
|
statusParts.push_back(tr::lng_edited(tr::now));
|
|
}
|
|
const auto dateTime = view->dateTime();
|
|
statusParts.push_back(
|
|
tr::lng_schedule_at(tr::now)
|
|
+ u" "_q
|
|
+ QLocale().toString(dateTime.time(), QLocale::ShortFormat));
|
|
if (const auto views = item->Get<HistoryMessageViews>()) {
|
|
if (views->views.count >= 0) {
|
|
statusParts.push_back(
|
|
QString::number(views->views.count)
|
|
+ u" "_q
|
|
+ tr::lng_stats_overview_message_views(tr::now));
|
|
}
|
|
}
|
|
if (const auto signed_ = item->Get<HistoryMessageSigned>()) {
|
|
if (!signed_->author.isEmpty()) {
|
|
statusParts.push_back(signed_->author);
|
|
}
|
|
}
|
|
lines.push_back(statusParts.join(u" "_q));
|
|
|
|
const auto &reactions = item->reactions();
|
|
if (!reactions.empty()) {
|
|
QStringList reactionParts;
|
|
for (const auto &reaction : reactions) {
|
|
auto text = reaction.id.emoji();
|
|
if (text.isEmpty()) {
|
|
if (const auto customId = reaction.id.custom()) {
|
|
const auto doc = item->history()->owner().document(
|
|
customId);
|
|
if (const auto sticker = doc->sticker()) {
|
|
text = tr::lng_sr_message_custom_emoji(
|
|
tr::now,
|
|
lt_emoji,
|
|
sticker->alt);
|
|
}
|
|
}
|
|
}
|
|
if (!text.isEmpty()) {
|
|
if (reaction.count > 1) {
|
|
reactionParts.push_back(
|
|
text + u" "_q + QString::number(reaction.count));
|
|
} else {
|
|
reactionParts.push_back(text);
|
|
}
|
|
}
|
|
}
|
|
if (!reactionParts.isEmpty()) {
|
|
lines.push_back(tr::lng_notification_reactions(tr::now)
|
|
+ u": "_q
|
|
+ reactionParts.join(u", "_q));
|
|
}
|
|
}
|
|
|
|
return lines.join(u"\n"_q);
|
|
}
|
|
|
|
QString UnreadBarAccessibilityName(not_null<const Element*> barElement) {
|
|
if (const auto bar = barElement->Get<HistoryView::UnreadBar>()) {
|
|
return bar->text;
|
|
}
|
|
return tr::lng_unread_bar_some(tr::now);
|
|
}
|
|
|
|
QString MessageSubItemLabel(MessageSubItem item) {
|
|
switch (item) {
|
|
case MessageSubItem::Seen:
|
|
return tr::lng_sr_message_seen(tr::now);
|
|
case MessageSubItem::Sender:
|
|
return tr::lng_sr_chat_column_sender(tr::now);
|
|
case MessageSubItem::ViaBot:
|
|
return tr::lng_inline_bot_via(tr::now, lt_inline_bot, QString());
|
|
case MessageSubItem::Reply:
|
|
return tr::lng_notification_reply(tr::now);
|
|
case MessageSubItem::Forward:
|
|
return tr::lng_sr_chat_column_forward(tr::now);
|
|
case MessageSubItem::MediaType:
|
|
return tr::lng_sr_message_column_media_type(tr::now);
|
|
case MessageSubItem::Download:
|
|
return tr::lng_media_download(tr::now);
|
|
case MessageSubItem::Played:
|
|
return tr::lng_sr_message_played(tr::now);
|
|
case MessageSubItem::Artist:
|
|
return tr::lng_sr_message_column_artist(tr::now);
|
|
case MessageSubItem::Title:
|
|
return tr::lng_sr_message_column_title(tr::now);
|
|
case MessageSubItem::Filename:
|
|
return tr::lng_sr_message_column_filename(tr::now);
|
|
case MessageSubItem::Duration:
|
|
return tr::lng_sr_message_column_duration(tr::now);
|
|
case MessageSubItem::Dimensions:
|
|
return tr::lng_sr_message_column_dimensions(tr::now);
|
|
case MessageSubItem::FileSize:
|
|
return tr::lng_sr_message_column_file_size(tr::now);
|
|
case MessageSubItem::Message:
|
|
return tr::lng_sr_chat_column_message(tr::now);
|
|
case MessageSubItem::Delivery:
|
|
return tr::lng_sr_chat_column_delivery(tr::now);
|
|
case MessageSubItem::Edited:
|
|
return tr::lng_edited(tr::now);
|
|
case MessageSubItem::Time:
|
|
return tr::lng_sr_chat_column_time(tr::now);
|
|
case MessageSubItem::Reactions:
|
|
return tr::lng_notification_reactions(tr::now);
|
|
case MessageSubItem::Views:
|
|
return tr::lng_stats_overview_message_views(tr::now);
|
|
case MessageSubItem::Signature:
|
|
return tr::lng_sr_message_column_signature(tr::now);
|
|
case MessageSubItem::Pinned:
|
|
return tr::lng_sr_chat_pinned(tr::now);
|
|
case MessageSubItem::WebSite:
|
|
return tr::lng_sr_message_column_web_site(tr::now);
|
|
case MessageSubItem::WebTitle:
|
|
return tr::lng_sr_message_column_web_title(tr::now);
|
|
case MessageSubItem::WebDescription:
|
|
return tr::lng_sr_message_column_web_description(tr::now);
|
|
case MessageSubItem::PollQuestion:
|
|
return tr::lng_sr_message_column_poll_question(tr::now);
|
|
case MessageSubItem::PollOptions:
|
|
return tr::lng_polls_create_options(tr::now);
|
|
case MessageSubItem::PollStatus:
|
|
return tr::lng_sr_message_column_poll_status(tr::now);
|
|
case MessageSubItem::ContactName:
|
|
return tr::lng_sr_message_column_contact_name(tr::now);
|
|
case MessageSubItem::ContactPhone:
|
|
return tr::lng_sr_message_column_contact_phone(tr::now);
|
|
case MessageSubItem::Location:
|
|
return tr::lng_sr_message_column_location(tr::now);
|
|
case MessageSubItem::StickerEmoji:
|
|
return tr::lng_sr_message_column_sticker_emoji(tr::now);
|
|
case MessageSubItem::GameTitle:
|
|
return tr::lng_sr_message_column_game_title(tr::now);
|
|
case MessageSubItem::GameDescription:
|
|
return tr::lng_sr_message_column_game_description(tr::now);
|
|
case MessageSubItem::InvoiceTitle:
|
|
return tr::lng_sr_message_column_invoice_title(tr::now);
|
|
case MessageSubItem::InvoiceAmount:
|
|
return tr::lng_sr_message_column_invoice_amount(tr::now);
|
|
case MessageSubItem::Spoiler:
|
|
return tr::lng_sr_message_column_spoiler(tr::now);
|
|
case MessageSubItem::Dice:
|
|
return tr::lng_sr_message_column_dice(tr::now);
|
|
case MessageSubItem::Giveaway:
|
|
return tr::lng_sr_message_column_giveaway(tr::now);
|
|
case MessageSubItem::Gift:
|
|
return tr::lng_sr_message_column_gift(tr::now);
|
|
case MessageSubItem::TodoTitle:
|
|
return tr::lng_sr_message_column_todo_title(tr::now);
|
|
case MessageSubItem::TodoItems:
|
|
return tr::lng_sr_message_column_todo_items(tr::now);
|
|
case MessageSubItem::Factcheck:
|
|
return tr::lng_sr_message_column_factcheck(tr::now);
|
|
case MessageSubItem::ForwardDate:
|
|
return tr::lng_sr_message_column_forward_date(tr::now);
|
|
case MessageSubItem::ForwardAuthor:
|
|
return tr::lng_sr_message_column_forward_author(tr::now);
|
|
case MessageSubItem::PaidReactions:
|
|
return tr::lng_sr_message_column_paid_reactions(tr::now);
|
|
case MessageSubItem::Count:
|
|
break;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
QString MessageSubItemValue(
|
|
not_null<const Element*> view,
|
|
not_null<History*> history,
|
|
MessageSubItem item) {
|
|
const auto data = view->data();
|
|
if (data->isService()) {
|
|
if (item == MessageSubItem::Message) {
|
|
return data->notificationText().text;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
switch (item) {
|
|
case MessageSubItem::Seen:
|
|
if (data->out()) {
|
|
return data->unread(history)
|
|
? tr::lng_sr_message_not_seen(tr::now)
|
|
: tr::lng_sr_message_seen(tr::now);
|
|
}
|
|
return {};
|
|
case MessageSubItem::Sender:
|
|
if (data->out()) {
|
|
return tr::lng_sr_from_me(tr::now);
|
|
} else if (const auto from = data->displayFrom()) {
|
|
return from->name();
|
|
}
|
|
return {};
|
|
case MessageSubItem::ViaBot:
|
|
if (const auto bot = data->viaBot()) {
|
|
return tr::lng_inline_bot_via(
|
|
tr::now,
|
|
lt_inline_bot,
|
|
'@' + bot->username());
|
|
}
|
|
return {};
|
|
case MessageSubItem::Reply:
|
|
if (const auto reply = data->Get<HistoryMessageReply>()) {
|
|
if (const auto message = reply->resolvedMessage.get()) {
|
|
const auto replyFrom = message->displayFrom();
|
|
const auto replyName = replyFrom
|
|
? replyFrom->name()
|
|
: QString();
|
|
const auto replyText = message->inReplyText().text;
|
|
if (!replyName.isEmpty() || !replyText.isEmpty()) {
|
|
return tr::lng_sr_message_reply_to(
|
|
tr::now,
|
|
lt_name,
|
|
replyName.isEmpty()
|
|
? tr::lng_sr_from_me(tr::now)
|
|
: replyName,
|
|
lt_text,
|
|
replyText);
|
|
}
|
|
}
|
|
}
|
|
return {};
|
|
case MessageSubItem::Forward:
|
|
if (const auto fwd = data->Get<HistoryMessageForwarded>()) {
|
|
if (fwd->originalSender) {
|
|
return tr::lng_forwarded(
|
|
tr::now,
|
|
lt_user,
|
|
fwd->originalSender->name());
|
|
} else if (fwd->originalHiddenSenderInfo) {
|
|
return tr::lng_forwarded(
|
|
tr::now,
|
|
lt_user,
|
|
fwd->originalHiddenSenderInfo->name);
|
|
}
|
|
}
|
|
return {};
|
|
case MessageSubItem::MediaType: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
if (const auto document = media->document()) {
|
|
if (document->isVoiceMessage()) {
|
|
return tr::lng_in_dlg_audio(tr::now);
|
|
} else if (document->isVideoMessage()) {
|
|
return tr::lng_in_dlg_video_message(tr::now);
|
|
} else if (document->isSong()) {
|
|
return tr::lng_in_dlg_audio_file(tr::now);
|
|
} else if (document->isVideoFile()) {
|
|
return tr::lng_in_dlg_video(tr::now);
|
|
} else if (document->isAnimation()) {
|
|
return u"GIF"_q;
|
|
} else if (document->sticker()) {
|
|
return tr::lng_in_dlg_sticker(tr::now);
|
|
}
|
|
return tr::lng_in_dlg_file(tr::now);
|
|
} else if (media->photo()) {
|
|
return tr::lng_in_dlg_photo(tr::now);
|
|
} else if (media->call()) {
|
|
return data->notificationText().text;
|
|
}
|
|
return data->notificationText().text;
|
|
}
|
|
case MessageSubItem::Download: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto document = media->document();
|
|
if (!document) {
|
|
return {};
|
|
}
|
|
if (document->loading()) {
|
|
return tr::lng_sr_message_downloading(tr::now);
|
|
} else if (!document->filepath(true).isEmpty()
|
|
|| document->loadedInMediaCache()) {
|
|
return tr::lng_emoji_set_ready(tr::now);
|
|
}
|
|
return tr::lng_sr_message_not_downloaded(tr::now);
|
|
}
|
|
case MessageSubItem::Played: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto document = media->document();
|
|
if (!document) {
|
|
return {};
|
|
}
|
|
if (document->isVoiceMessage()
|
|
|| document->isVideoMessage()) {
|
|
return data->isUnreadMedia()
|
|
? tr::lng_sr_message_not_played(tr::now)
|
|
: tr::lng_sr_message_played(tr::now);
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Artist: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto document = media->document();
|
|
if (!document) {
|
|
return {};
|
|
}
|
|
if (const auto song = document->song()) {
|
|
return song->performer;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Title: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto document = media->document();
|
|
if (!document) {
|
|
return {};
|
|
}
|
|
if (const auto song = document->song()) {
|
|
return song->title;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Filename: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto document = media->document();
|
|
if (!document
|
|
|| document->isSong()
|
|
|| document->isVoiceMessage()
|
|
|| document->isVideoMessage()
|
|
|| document->sticker()) {
|
|
return {};
|
|
}
|
|
return document->filename();
|
|
}
|
|
case MessageSubItem::Duration: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
if (const auto document = media->document()) {
|
|
const auto duration = document->duration();
|
|
if (duration > 0) {
|
|
return Ui::FormatDurationText(duration / 1000);
|
|
}
|
|
} else if (const auto call = media->call()) {
|
|
if (call->duration > 0) {
|
|
return Ui::FormatDurationText(call->duration);
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Dimensions: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
if (const auto document = media->document()) {
|
|
if (!document->dimensions.isEmpty()
|
|
&& (document->isVideoFile()
|
|
|| document->isImage())) {
|
|
return Ui::FormatImageSizeText(document->dimensions);
|
|
}
|
|
} else if (const auto photo = media->photo()) {
|
|
const auto large = photo->size(
|
|
Data::PhotoSize::Large);
|
|
if (large && !large->isEmpty()) {
|
|
return Ui::FormatImageSizeText(*large);
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::FileSize: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto document = media->document();
|
|
if (!document || document->size <= 0) {
|
|
return {};
|
|
}
|
|
return Ui::FormatSizeText(document->size);
|
|
}
|
|
case MessageSubItem::Message: {
|
|
if (data->media()) {
|
|
return data->originalText().text;
|
|
}
|
|
return data->originalText().text;
|
|
}
|
|
case MessageSubItem::Delivery:
|
|
if (data->out()) {
|
|
if (data->isSending()) {
|
|
return tr::lng_sr_chat_sending(tr::now);
|
|
} else if (data->hasFailed()) {
|
|
return tr::lng_sr_chat_failed(tr::now);
|
|
}
|
|
return tr::lng_sr_chat_sent(tr::now);
|
|
}
|
|
return tr::lng_sr_chat_received(tr::now);
|
|
case MessageSubItem::Edited:
|
|
if (data->Has<HistoryMessageEdited>()) {
|
|
return tr::lng_edited(tr::now);
|
|
}
|
|
return {};
|
|
case MessageSubItem::Time: {
|
|
const auto dateTime = view->dateTime();
|
|
return tr::lng_schedule_at(tr::now)
|
|
+ u" "_q
|
|
+ QLocale().toString(dateTime.time(), QLocale::ShortFormat);
|
|
}
|
|
case MessageSubItem::Reactions: {
|
|
const auto &reactions = data->reactions();
|
|
if (reactions.empty()) {
|
|
return {};
|
|
}
|
|
QStringList reactionParts;
|
|
for (const auto &reaction : reactions) {
|
|
auto text = reaction.id.emoji();
|
|
if (text.isEmpty()) {
|
|
if (const auto customId = reaction.id.custom()) {
|
|
const auto doc = data->history()->owner().document(
|
|
customId);
|
|
if (const auto sticker = doc->sticker()) {
|
|
text = tr::lng_sr_message_custom_emoji(
|
|
tr::now,
|
|
lt_emoji,
|
|
sticker->alt);
|
|
}
|
|
}
|
|
}
|
|
if (!text.isEmpty()) {
|
|
if (reaction.count > 1) {
|
|
reactionParts.push_back(
|
|
text + u" "_q + QString::number(reaction.count));
|
|
} else {
|
|
reactionParts.push_back(text);
|
|
}
|
|
}
|
|
}
|
|
return reactionParts.join(u", "_q);
|
|
}
|
|
case MessageSubItem::Views: {
|
|
const auto views = data->Get<HistoryMessageViews>();
|
|
if (views && views->views.count >= 0) {
|
|
return QString::number(views->views.count);
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Signature: {
|
|
const auto signed_ = data->Get<HistoryMessageSigned>();
|
|
if (signed_ && !signed_->author.isEmpty()) {
|
|
return signed_->author;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Pinned:
|
|
if (data->isPinned()) {
|
|
return tr::lng_sr_chat_pinned(tr::now);
|
|
}
|
|
return {};
|
|
case MessageSubItem::WebSite: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto webpage = media->webpage();
|
|
if (webpage) {
|
|
return webpage->siteName;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::WebTitle: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto webpage = media->webpage();
|
|
if (webpage) {
|
|
return webpage->title;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::WebDescription: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto webpage = media->webpage();
|
|
if (webpage) {
|
|
return webpage->description.text;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::PollQuestion: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto poll = media->poll();
|
|
if (poll) {
|
|
return poll->question.text;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::PollOptions: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto poll = media->poll();
|
|
if (!poll) {
|
|
return {};
|
|
}
|
|
QStringList options;
|
|
for (const auto &answer : poll->answers) {
|
|
auto line = answer.text.text;
|
|
if (poll->totalVoters > 0 && answer.votes > 0) {
|
|
const auto percent = (answer.votes * 100)
|
|
/ poll->totalVoters;
|
|
line += u" ("_q
|
|
+ QString::number(percent)
|
|
+ u"%, "_q
|
|
+ QString::number(answer.votes)
|
|
+ u")"_q;
|
|
}
|
|
if (answer.chosen) {
|
|
line += u" ✓"_q;
|
|
}
|
|
if (answer.correct) {
|
|
line += u" ✔"_q;
|
|
}
|
|
options.push_back(line);
|
|
}
|
|
return options.join(u"; "_q);
|
|
}
|
|
case MessageSubItem::PollStatus: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto poll = media->poll();
|
|
if (!poll) {
|
|
return {};
|
|
}
|
|
QStringList parts;
|
|
parts.push_back(poll->quiz()
|
|
? tr::lng_polls_public_quiz(tr::now)
|
|
: tr::lng_polls_public(tr::now));
|
|
if (poll->closed()) {
|
|
parts.push_back(
|
|
tr::lng_hours_closed(tr::now));
|
|
}
|
|
parts.push_back(tr::lng_polls_votes_count(
|
|
tr::now,
|
|
lt_count,
|
|
poll->totalVoters));
|
|
return parts.join(u", "_q);
|
|
}
|
|
case MessageSubItem::ContactName: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto contact = media->sharedContact();
|
|
if (!contact) {
|
|
return {};
|
|
}
|
|
auto name = contact->firstName;
|
|
if (!contact->lastName.isEmpty()) {
|
|
if (!name.isEmpty()) {
|
|
name += u" "_q;
|
|
}
|
|
name += contact->lastName;
|
|
}
|
|
return name;
|
|
}
|
|
case MessageSubItem::ContactPhone: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto contact = media->sharedContact();
|
|
if (contact) {
|
|
return contact->phoneNumber;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Location: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
if (media->location()) {
|
|
return data->notificationText().text;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::StickerEmoji: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto document = media->document();
|
|
if (!document) {
|
|
return {};
|
|
}
|
|
if (const auto sticker = document->sticker()) {
|
|
return sticker->alt;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::GameTitle: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto game = media->game();
|
|
if (game) {
|
|
return game->title;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::GameDescription: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto game = media->game();
|
|
if (game) {
|
|
return game->description;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::InvoiceTitle: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto invoice = media->invoice();
|
|
if (invoice) {
|
|
return invoice->title;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::InvoiceAmount: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto invoice = media->invoice();
|
|
if (!invoice) {
|
|
return {};
|
|
}
|
|
auto result = invoice->currency
|
|
+ u" "_q
|
|
+ QString::number(invoice->amount / 100.0, 'f', 2);
|
|
if (invoice->receiptMsgId) {
|
|
result += u" ("_q
|
|
+ tr::lng_sr_message_invoice_paid(tr::now)
|
|
+ u")"_q;
|
|
} else {
|
|
result += u" ("_q
|
|
+ tr::lng_sr_message_invoice_unpaid(tr::now)
|
|
+ u")"_q;
|
|
}
|
|
return result;
|
|
}
|
|
case MessageSubItem::Spoiler: {
|
|
const auto media = data->media();
|
|
if (media && media->hasSpoiler()) {
|
|
return tr::lng_sr_message_spoiler(tr::now);
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Dice: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto notification = data->notificationText().text;
|
|
if (media->game() || media->poll()) {
|
|
return {};
|
|
}
|
|
if (!media->document()
|
|
&& !media->photo()
|
|
&& !media->sharedContact()
|
|
&& !media->location()
|
|
&& !media->invoice()
|
|
&& !media->giveawayStart()
|
|
&& !media->giveawayResults()
|
|
&& !media->gift()
|
|
&& !media->todolist()
|
|
&& !media->game()
|
|
&& !media->poll()
|
|
&& !media->webpage()
|
|
&& !notification.isEmpty()) {
|
|
return notification;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Giveaway: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
if (const auto giveaway = media->giveawayStart()) {
|
|
QStringList parts;
|
|
if (giveaway->quantity > 0) {
|
|
parts.push_back(QString::number(giveaway->quantity)
|
|
+ u" winners"_q);
|
|
}
|
|
if (giveaway->months > 0) {
|
|
parts.push_back(QString::number(giveaway->months)
|
|
+ u" months Premium"_q);
|
|
}
|
|
if (giveaway->credits > 0) {
|
|
parts.push_back(QString::number(giveaway->credits)
|
|
+ u" stars"_q);
|
|
}
|
|
if (!giveaway->additionalPrize.isEmpty()) {
|
|
parts.push_back(giveaway->additionalPrize);
|
|
}
|
|
return parts.join(u", "_q);
|
|
}
|
|
if (const auto results = media->giveawayResults()) {
|
|
QStringList parts;
|
|
parts.push_back(QString::number(results->winnersCount)
|
|
+ u" winners"_q);
|
|
if (results->unclaimedCount > 0) {
|
|
parts.push_back(QString::number(results->unclaimedCount)
|
|
+ u" unclaimed"_q);
|
|
}
|
|
if (results->refunded) {
|
|
parts.push_back(u"refunded"_q);
|
|
}
|
|
return parts.join(u", "_q);
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Gift: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto gift = media->gift();
|
|
if (!gift) {
|
|
return {};
|
|
}
|
|
switch (gift->type) {
|
|
case Data::GiftType::Premium:
|
|
return tr::lng_sr_message_gift_premium(
|
|
tr::now,
|
|
lt_count,
|
|
gift->count);
|
|
case Data::GiftType::Credits:
|
|
case Data::GiftType::StarGift:
|
|
return tr::lng_sr_message_gift_credits(
|
|
tr::now,
|
|
lt_count,
|
|
gift->count);
|
|
default:
|
|
if (!gift->giftTitle.isEmpty()) {
|
|
return gift->giftTitle;
|
|
}
|
|
return {};
|
|
}
|
|
}
|
|
case MessageSubItem::TodoTitle: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto todolist = media->todolist();
|
|
if (todolist) {
|
|
return todolist->title.text;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::TodoItems: {
|
|
const auto media = data->media();
|
|
if (!media) {
|
|
return {};
|
|
}
|
|
const auto todolist = media->todolist();
|
|
if (!todolist) {
|
|
return {};
|
|
}
|
|
QStringList items;
|
|
for (const auto &todoItem : todolist->items) {
|
|
auto line = todoItem.text.text;
|
|
line += u" ("_q;
|
|
line += todoItem.completedBy
|
|
? tr::lng_sr_message_todo_completed(tr::now)
|
|
: tr::lng_sr_message_todo_not_completed(tr::now);
|
|
line += u")"_q;
|
|
items.push_back(line);
|
|
}
|
|
return items.join(u"; "_q);
|
|
}
|
|
case MessageSubItem::Factcheck: {
|
|
const auto text = data->factcheckText();
|
|
if (!text.empty()) {
|
|
return text.text;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::ForwardDate: {
|
|
const auto fwd = data->Get<HistoryMessageForwarded>();
|
|
if (!fwd) {
|
|
return {};
|
|
}
|
|
if (fwd->originalDate) {
|
|
const auto dt = base::unixtime::parse(fwd->originalDate);
|
|
return QLocale().toString(dt, QLocale::ShortFormat);
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::ForwardAuthor: {
|
|
const auto fwd = data->Get<HistoryMessageForwarded>();
|
|
if (!fwd) {
|
|
return {};
|
|
}
|
|
if (!fwd->originalPostAuthor.isEmpty()) {
|
|
return fwd->originalPostAuthor;
|
|
}
|
|
if (fwd->imported) {
|
|
return u"Imported"_q;
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::PaidReactions: {
|
|
const auto &reactions = data->reactions();
|
|
for (const auto &reaction : reactions) {
|
|
if (reaction.id.paid() && reaction.count > 0) {
|
|
return QString::number(reaction.count);
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
case MessageSubItem::Count:
|
|
break;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
std::vector<MessageSubItem> ActiveMessageSubItems(
|
|
not_null<const Element*> view,
|
|
not_null<History*> history) {
|
|
auto result = std::vector<MessageSubItem>();
|
|
result.reserve(int(MessageSubItem::Count));
|
|
for (auto i = 0; i != int(MessageSubItem::Count); ++i) {
|
|
const auto item = MessageSubItem(i);
|
|
if (!MessageSubItemValue(view, history, item).isEmpty()) {
|
|
result.push_back(item);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
} // namespace HistoryView
|