2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-09-02 15:45:12 +00:00

Support for game keyboard buttons and score service messages added.

This commit is contained in:
John Preston
2016-09-02 12:11:23 -04:00
parent 167adc652b
commit 160895f6e3
8 changed files with 629 additions and 118 deletions

View File

@@ -676,7 +676,7 @@ void checkForSwitchInlineButton(HistoryItem *item) {
if (auto markup = item->Get<HistoryMessageReplyMarkup>()) {
for_const (const auto &row, markup->rows) {
for_const (const auto &button, row) {
if (button.type == HistoryMessageReplyMarkup::Button::SwitchInline) {
if (button.type == HistoryMessageReplyMarkup::Button::Type::SwitchInline) {
Notify::switchInlineBotButtonReceived(QString::fromUtf8(button.data));
return;
}
@@ -2222,7 +2222,7 @@ public:
// Copy to clipboard support.
void copyToClipboard() const override {
if (auto button = getButton()) {
if (button->type == HistoryMessageReplyMarkup::Button::Url) {
if (button->type == HistoryMessageReplyMarkup::Button::Type::Url) {
auto url = QString::fromUtf8(button->data);
if (!url.isEmpty()) {
QApplication::clipboard()->setText(url);
@@ -2232,7 +2232,7 @@ public:
}
QString copyToClipboardContextItemText() const override {
if (auto button = getButton()) {
if (button->type == HistoryMessageReplyMarkup::Button::Url) {
if (button->type == HistoryMessageReplyMarkup::Button::Type::Url) {
return lang(lng_context_copy_link);
}
}
@@ -2514,8 +2514,9 @@ void ReplyKeyboard::Style::paintButton(Painter &p, const ReplyKeyboard::Button &
paintButtonBg(p, rect, pressed, button.howMuchOver);
paintButtonIcon(p, rect, button.type);
if (button.type == HistoryMessageReplyMarkup::Button::Callback) {
if (const HistoryMessageReplyMarkup::Button *data = button.link->getButton()) {
if (button.type == HistoryMessageReplyMarkup::Button::Type::Callback
|| button.type == HistoryMessageReplyMarkup::Button::Type::Game) {
if (auto data = button.link->getButton()) {
if (data->requestId) {
paintButtonLoading(p, rect);
}
@@ -2552,32 +2553,37 @@ void HistoryMessageReplyMarkup::createFromButtonRows(const QVector<MTPKeyboardBu
for_const (const auto &button, b) {
switch (button.type()) {
case mtpc_keyboardButton: {
buttonRow.push_back({ Button::Default, qs(button.c_keyboardButton().vtext), QByteArray(), 0 });
buttonRow.push_back({ Button::Type::Default, qs(button.c_keyboardButton().vtext), QByteArray(), 0 });
} break;
case mtpc_keyboardButtonCallback: {
const auto &buttonData(button.c_keyboardButtonCallback());
buttonRow.push_back({ Button::Callback, qs(buttonData.vtext), qba(buttonData.vdata), 0 });
auto &buttonData = button.c_keyboardButtonCallback();
buttonRow.push_back({ Button::Type::Callback, qs(buttonData.vtext), qba(buttonData.vdata), 0 });
} break;
case mtpc_keyboardButtonRequestGeoLocation: {
buttonRow.push_back({ Button::RequestLocation, qs(button.c_keyboardButtonRequestGeoLocation().vtext), QByteArray(), 0 });
buttonRow.push_back({ Button::Type::RequestLocation, qs(button.c_keyboardButtonRequestGeoLocation().vtext), QByteArray(), 0 });
} break;
case mtpc_keyboardButtonRequestPhone: {
buttonRow.push_back({ Button::RequestPhone, qs(button.c_keyboardButtonRequestPhone().vtext), QByteArray(), 0 });
buttonRow.push_back({ Button::Type::RequestPhone, qs(button.c_keyboardButtonRequestPhone().vtext), QByteArray(), 0 });
} break;
case mtpc_keyboardButtonUrl: {
const auto &buttonData(button.c_keyboardButtonUrl());
buttonRow.push_back({ Button::Url, qs(buttonData.vtext), qba(buttonData.vurl), 0 });
auto &buttonData = button.c_keyboardButtonUrl();
buttonRow.push_back({ Button::Type::Url, qs(buttonData.vtext), qba(buttonData.vurl), 0 });
} break;
case mtpc_keyboardButtonSwitchInline: {
auto &buttonData = button.c_keyboardButtonSwitchInline();
auto buttonType = buttonData.is_same_peer() ? Button::SwitchInlineSame : Button::SwitchInline;
auto buttonType = buttonData.is_same_peer() ? Button::Type::SwitchInlineSame : Button::Type::SwitchInline;
buttonRow.push_back({ buttonType, qs(buttonData.vtext), qba(buttonData.vquery), 0 });
if (buttonType == Button::SwitchInline) {
if (buttonType == Button::Type::SwitchInline) {
// Optimization flag.
// Fast check on all new messages if there is a switch button to auto-click it.
flags |= MTPDreplyKeyboardMarkup_ClientFlag::f_has_switch_inline_button;
}
} break;
case mtpc_keyboardButtonGame: {
auto &buttonData = button.c_keyboardButtonGame();
auto strData = QString::number(buttonData.vgame_id.v) + ',' + qs(buttonData.vgame_title);
buttonRow.push_back({ Button::Type::Game, qs(buttonData.vtext), strData.toUtf8(), 0 });
} break;
}
}
if (!buttonRow.isEmpty()) rows.push_back(buttonRow);
@@ -6612,11 +6618,11 @@ void HistoryMessage::KeyboardStyle::paintButtonIcon(Painter &p, const QRect &rec
using Button = HistoryMessageReplyMarkup::Button;
style::sprite sprite;
switch (type) {
case Button::Url: sprite = st::msgBotKbUrlIcon; break;
// case Button::RequestPhone: sprite = st::msgBotKbRequestPhoneIcon; break;
// case Button::RequestLocation: sprite = st::msgBotKbRequestLocationIcon; break;
case Button::SwitchInlineSame:
case Button::SwitchInline: sprite = st::msgBotKbSwitchPmIcon; break;
case Button::Type::Url: sprite = st::msgBotKbUrlIcon; break;
// case Button::Type::RequestPhone: sprite = st::msgBotKbRequestPhoneIcon; break;
// case Button::Type::RequestLocation: sprite = st::msgBotKbRequestLocationIcon; break;
case Button::Type::SwitchInlineSame:
case Button::Type::SwitchInline: sprite = st::msgBotKbSwitchPmIcon; break;
}
if (!sprite.isEmpty()) {
p.drawSprite(rect.x() + rect.width() - sprite.pxWidth() - st::msgBotKbIconPadding, rect.y() + st::msgBotKbIconPadding, sprite);
@@ -6632,12 +6638,13 @@ int HistoryMessage::KeyboardStyle::minButtonWidth(HistoryMessageReplyMarkup::But
using Button = HistoryMessageReplyMarkup::Button;
int result = 2 * buttonPadding(), iconWidth = 0;
switch (type) {
case Button::Url: iconWidth = st::msgBotKbUrlIcon.pxWidth(); break;
//case Button::RequestPhone: iconWidth = st::msgBotKbRequestPhoneIcon.pxWidth(); break;
//case Button::RequestLocation: iconWidth = st::msgBotKbRequestLocationIcon.pxWidth(); break;
case Button::SwitchInlineSame:
case Button::SwitchInline: iconWidth = st::msgBotKbSwitchPmIcon.pxWidth(); break;
case Button::Callback: iconWidth = st::msgInvSendingImg.pxWidth(); break;
case Button::Type::Url: iconWidth = st::msgBotKbUrlIcon.pxWidth(); break;
//case Button::Type::RequestPhone: iconWidth = st::msgBotKbRequestPhoneIcon.pxWidth(); break;
//case Button::Type::RequestLocation: iconWidth = st::msgBotKbRequestLocationIcon.pxWidth(); break;
case Button::Type::SwitchInlineSame:
case Button::Type::SwitchInline: iconWidth = st::msgBotKbSwitchPmIcon.pxWidth(); break;
case Button::Type::Callback:
case Button::Type::Game: iconWidth = st::msgInvSendingImg.pxWidth(); break;
}
if (iconWidth > 0) {
result = std::max(result, 2 * iconWidth + 4 * int(st::msgBotKbIconPadding));
@@ -8005,6 +8012,10 @@ void HistoryService::setMessageByAction(const MTPmessageAction &action) {
}
} break;
case mtpc_messageActionGameScore: {
updateGameScoreText(&text);
} break;
default: from = QString(); break;
}
@@ -8019,42 +8030,42 @@ void HistoryService::setMessageByAction(const MTPmessageAction &action) {
}
}
bool HistoryService::updatePinned(bool force) {
auto pinned = Get<HistoryServicePinned>();
t_assert(pinned != nullptr);
bool HistoryService::updateDependent(bool force) {
auto dependent = GetDependentData();
t_assert(dependent != nullptr);
if (!force) {
if (!pinned->msgId || pinned->msg) {
if (!dependent->msgId || dependent->msg) {
return true;
}
}
if (!pinned->lnk) {
pinned->lnk.reset(new GoToMessageClickHandler(history()->peer->id, pinned->msgId));
if (!dependent->lnk) {
dependent->lnk.reset(new GoToMessageClickHandler(history()->peer->id, dependent->msgId));
}
bool gotDependencyItem = false;
if (!pinned->msg) {
pinned->msg = App::histItemById(channelId(), pinned->msgId);
if (pinned->msg) {
App::historyRegDependency(this, pinned->msg);
if (!dependent->msg) {
dependent->msg = App::histItemById(channelId(), dependent->msgId);
if (dependent->msg) {
App::historyRegDependency(this, dependent->msg);
gotDependencyItem = true;
}
}
if (pinned->msg) {
updatePinnedText();
if (dependent->msg) {
updateDependentText();
} else if (force) {
if (pinned->msgId > 0) {
pinned->msgId = 0;
if (dependent->msgId > 0) {
dependent->msgId = 0;
gotDependencyItem = true;
}
updatePinnedText();
updateDependentText();
}
if (force) {
if (gotDependencyItem && App::wnd()) {
App::wnd()->notifySettingGot();
}
}
return (pinned->msg || !pinned->msgId);
return (dependent->msg || !dependent->msgId);
}
bool HistoryService::updatePinnedText(const QString *pfrom, QString *ptext) {
@@ -8129,13 +8140,62 @@ bool HistoryService::updatePinnedText(const QString *pfrom, QString *ptext) {
return result;
}
bool HistoryService::updateGameScoreText(QString *ptext) {
bool result = false;
QString from = _from->name, text;
auto gamescore = Get<HistoryServiceGameScore>();
if (gamescore && gamescore->msg) {
auto getGameTitle = [item = gamescore->msg]() -> QString {
if (auto markup = item->Get<HistoryMessageReplyMarkup>()) {
for_const (auto &row, markup->rows) {
for_const (auto &button, row) {
if (button.type == HistoryMessageReplyMarkup::Button::Type::Game) {
auto strData = QString::fromUtf8(button.data);
return strData.mid(strData.indexOf(',') + 1);
}
}
}
}
return lang(lng_deleted_message);
};
text = lng_action_game_score(lt_from, from, lt_score, QString::number(gamescore->score), lt_game, getGameTitle());
result = true;
} else if (gamescore && gamescore->msgId) {
text = lng_action_game_score(lt_from, from, lt_score, QString::number(gamescore->score), lt_game, lang(lng_contacts_loading));
result = true;
} else {
text = lng_action_game_score(lt_from, from, lt_score, QString::number(gamescore->score), lt_game, lang(lng_deleted_message));
}
if (ptext) {
*ptext = text;
} else {
setServiceText(text);
if (history()->textCachedFor == this) {
history()->textCachedFor = 0;
}
if (App::main()) {
App::main()->dlgUpdated(history(), id);
}
App::historyUpdateDependent(this);
}
return result;
}
HistoryService::HistoryService(History *history, const MTPDmessageService &msg) :
HistoryItem(history, msg.vid.v, mtpCastFlags(msg.vflags.v), ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0) {
if (msg.has_reply_to_msg_id()) {
UpdateComponents(HistoryServicePinned::Bit());
MsgId pinnedMsgId = Get<HistoryServicePinned>()->msgId = msg.vreply_to_msg_id.v;
if (!updatePinned() && App::api()) {
App::api()->requestMessageData(history->peer->asChannel(), pinnedMsgId, std_::make_unique<HistoryDependentItemCallback>(fullId()));
if (msg.vaction.type() == mtpc_messageActionPinMessage) {
UpdateComponents(HistoryServicePinned::Bit());
} else if (msg.vaction.type() == mtpc_messageActionGameScore) {
UpdateComponents(HistoryServiceGameScore::Bit());
Get<HistoryServiceGameScore>()->score = msg.vaction.c_messageActionGameScore().vscore.v;
}
if (auto dependent = GetDependentData()) {
dependent->msgId = msg.vreply_to_msg_id.v;
if (!updateDependent() && App::api()) {
App::api()->requestMessageData(history->peer->asChannel(), dependent->msgId, std_::make_unique<HistoryDependentItemCallback>(fullId()));
}
}
}
setMessageByAction(msg.vaction);
@@ -8152,6 +8212,13 @@ void HistoryService::initDimensions() {
if (_media) _media->initDimensions();
}
bool HistoryService::updateDependencyItem() {
if (GetDependentData()) {
return updateDependent(true);
}
return HistoryItem::updateDependencyItem();
}
void HistoryService::countPositionAndSize(int32 &left, int32 &width) const {
left = st::msgServiceMargin.left();
int32 maxwidth = _history->width;
@@ -8294,7 +8361,14 @@ HistoryTextState HistoryService::getState(int x, int y, HistoryStateRequest requ
if (_media) {
height -= st::msgServiceMargin.top() + _media->height();
}
QRect trect(QRect(left, st::msgServiceMargin.top(), width, height).marginsAdded(-st::msgServicePadding));
auto outer = QRect(left, st::msgServiceMargin.top(), width, height);
auto trect = outer.marginsAdded(-st::msgServicePadding);
if (auto gamescore = Get<HistoryServiceGameScore>()) {
if (outer.contains(x, y)) {
result.link = gamescore->lnk;
return result;
}
}
if (trect.contains(x, y)) {
textstyleSet(&st::serviceTextStyle);
auto textRequest = request.forText();
@@ -8312,6 +8386,9 @@ void HistoryService::applyEditionToEmpty() {
setServiceText(QString());
removeMedia();
clearDependency();
UpdateComponents(0);
finishEditionToEmpty();
}
@@ -8350,12 +8427,16 @@ void HistoryService::eraseFromOverview() {
}
}
HistoryService::~HistoryService() {
if (auto pinned = Get<HistoryServicePinned>()) {
if (pinned->msg) {
App::historyUnregDependency(this, pinned->msg);
void HistoryService::clearDependency() {
if (auto dependent = GetDependentData()) {
if (dependent->msg) {
App::historyUnregDependency(this, dependent->msg);
}
}
}
HistoryService::~HistoryService() {
clearDependency();
_media.clear();
}