mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 15:13:57 +02:00
Added animation of send action for stickers to middle of text.
This commit is contained in:
parent
8c17e3e578
commit
436212bb88
8 changed files with 93 additions and 9 deletions
|
@ -405,6 +405,7 @@ public:
|
||||||
|
|
||||||
struct SendActionAnimationUpdate {
|
struct SendActionAnimationUpdate {
|
||||||
not_null<History*> history;
|
not_null<History*> history;
|
||||||
|
int left = 0;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
bool textUpdated = false;
|
bool textUpdated = false;
|
||||||
|
|
|
@ -171,6 +171,7 @@ InnerWidget::InnerWidget(
|
||||||
const Data::Session::SendActionAnimationUpdate &update) {
|
const Data::Session::SendActionAnimationUpdate &update) {
|
||||||
using RowPainter = Layout::RowPainter;
|
using RowPainter = Layout::RowPainter;
|
||||||
const auto updateRect = RowPainter::sendActionAnimationRect(
|
const auto updateRect = RowPainter::sendActionAnimationRect(
|
||||||
|
update.left,
|
||||||
update.width,
|
update.width,
|
||||||
update.height,
|
update.height,
|
||||||
width(),
|
width(),
|
||||||
|
|
|
@ -943,11 +943,24 @@ void RowPainter::paint(
|
||||||
paintCounterCallback);
|
paintCounterCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect RowPainter::sendActionAnimationRect(int animationWidth, int animationHeight, int fullWidth, bool textUpdated) {
|
QRect RowPainter::sendActionAnimationRect(
|
||||||
auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
int animationLeft,
|
||||||
auto namewidth = fullWidth - nameleft - st::dialogsPadding.x();
|
int animationWidth,
|
||||||
auto texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
int animationHeight,
|
||||||
return QRect(nameleft, texttop, textUpdated ? namewidth : animationWidth, animationHeight);
|
int fullWidth,
|
||||||
|
bool textUpdated) {
|
||||||
|
const auto nameleft = st::dialogsPadding.x()
|
||||||
|
+ st::dialogsPhotoSize
|
||||||
|
+ st::dialogsPhotoPadding;
|
||||||
|
const auto namewidth = fullWidth - nameleft - st::dialogsPadding.x();
|
||||||
|
const auto texttop = st::dialogsPadding.y()
|
||||||
|
+ st::msgNameFont->height
|
||||||
|
+ st::dialogsSkip;
|
||||||
|
return QRect(
|
||||||
|
nameleft + (textUpdated ? 0 : animationLeft),
|
||||||
|
texttop,
|
||||||
|
textUpdated ? namewidth : animationWidth,
|
||||||
|
animationHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaintCollapsedRow(
|
void PaintCollapsedRow(
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
crl::time ms,
|
crl::time ms,
|
||||||
bool displayUnreadInfo);
|
bool displayUnreadInfo);
|
||||||
static QRect sendActionAnimationRect(
|
static QRect sendActionAnimationRect(
|
||||||
|
int animationLeft,
|
||||||
int animationWidth,
|
int animationWidth,
|
||||||
int animationHeight,
|
int animationHeight,
|
||||||
int fullWidth,
|
int fullWidth,
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
#include "lang/lang_instance.h" // Instance::supportChoosingStickerReplacement
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
|
@ -39,6 +40,7 @@ constexpr auto kStatusShowClientsideSpeaking = 6 * crl::time(1000);
|
||||||
SendActionPainter::SendActionPainter(not_null<History*> history)
|
SendActionPainter::SendActionPainter(not_null<History*> history)
|
||||||
: _history(history)
|
: _history(history)
|
||||||
, _weak(&_history->session())
|
, _weak(&_history->session())
|
||||||
|
, _st(st::dialogsTextStyle)
|
||||||
, _sendActionText(st::dialogsTextWidthMin) {
|
, _sendActionText(st::dialogsTextWidthMin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,16 +132,29 @@ bool SendActionPainter::paint(
|
||||||
style::color color,
|
style::color color,
|
||||||
crl::time ms) {
|
crl::time ms) {
|
||||||
if (_sendActionAnimation) {
|
if (_sendActionAnimation) {
|
||||||
|
const auto animationWidth = _sendActionAnimation.width();
|
||||||
|
const auto extraAnimationWidth = _animationLeft
|
||||||
|
? animationWidth * 2
|
||||||
|
: 0;
|
||||||
|
const auto left =
|
||||||
|
(availableWidth < _animationLeft + extraAnimationWidth)
|
||||||
|
? 0
|
||||||
|
: _animationLeft;
|
||||||
_sendActionAnimation.paint(
|
_sendActionAnimation.paint(
|
||||||
p,
|
p,
|
||||||
color,
|
color,
|
||||||
x,
|
left + x,
|
||||||
y + st::normalFont->ascent,
|
y + st::normalFont->ascent,
|
||||||
outerWidth,
|
outerWidth,
|
||||||
ms);
|
ms);
|
||||||
auto animationWidth = _sendActionAnimation.width();
|
// availableWidth should be the same
|
||||||
|
// if an animation is in the middle of text.
|
||||||
|
if (!left) {
|
||||||
x += animationWidth;
|
x += animationWidth;
|
||||||
availableWidth -= animationWidth;
|
availableWidth -= _animationLeft
|
||||||
|
? extraAnimationWidth
|
||||||
|
: animationWidth;
|
||||||
|
}
|
||||||
p.setPen(color);
|
p.setPen(color);
|
||||||
_sendActionText.drawElided(p, x, y, availableWidth);
|
_sendActionText.drawElided(p, x, y, availableWidth);
|
||||||
return true;
|
return true;
|
||||||
|
@ -270,6 +285,30 @@ bool SendActionPainter::updateNeedsAnimating(crl::time now, bool force) {
|
||||||
_history->peer->isUser() ? QString() : user->firstName);
|
_history->peer->isUser() ? QString() : user->firstName);
|
||||||
if (!newTypingString.isEmpty()) {
|
if (!newTypingString.isEmpty()) {
|
||||||
_sendActionAnimation.start(action.type);
|
_sendActionAnimation.start(action.type);
|
||||||
|
|
||||||
|
// Add an animation to the middle of text.
|
||||||
|
using namespace Lang;
|
||||||
|
if (GetInstance().supportChoosingStickerReplacement()
|
||||||
|
&& (action.type == Type::ChooseSticker)) {
|
||||||
|
|
||||||
|
const auto index = newTypingString.lastIndexOf(
|
||||||
|
Lang::kChoosingStickerReplacement.utf8());
|
||||||
|
_animationLeft = (index == -1)
|
||||||
|
? 0
|
||||||
|
: _st.font->width(newTypingString, 0, index);
|
||||||
|
|
||||||
|
if (!_spacesCount) {
|
||||||
|
_spacesCount = std::ceil(
|
||||||
|
_sendActionAnimation.width()
|
||||||
|
/ _st.font->spacew);
|
||||||
|
}
|
||||||
|
newTypingString = newTypingString.replace(
|
||||||
|
Lang::kChoosingStickerReplacement.utf8(),
|
||||||
|
QString().fill(' ', _spacesCount));
|
||||||
|
} else {
|
||||||
|
_animationLeft = 0;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,6 +366,7 @@ bool SendActionPainter::updateNeedsAnimating(crl::time now, bool force) {
|
||||||
|| (sendActionResult && !anim::Disabled())) {
|
|| (sendActionResult && !anim::Disabled())) {
|
||||||
_history->peer->owner().updateSendActionAnimation({
|
_history->peer->owner().updateSendActionAnimation({
|
||||||
_history,
|
_history,
|
||||||
|
_animationLeft,
|
||||||
_sendActionAnimation.width(),
|
_sendActionAnimation.width(),
|
||||||
st::normalFont->height,
|
st::normalFont->height,
|
||||||
(force || sendActionChanged)
|
(force || sendActionChanged)
|
||||||
|
|
|
@ -54,6 +54,7 @@ public:
|
||||||
private:
|
private:
|
||||||
const not_null<History*> _history;
|
const not_null<History*> _history;
|
||||||
const base::weak_ptr<Main::Session> _weak;
|
const base::weak_ptr<Main::Session> _weak;
|
||||||
|
const style::TextStyle &_st;
|
||||||
base::flat_map<not_null<UserData*>, crl::time> _typing;
|
base::flat_map<not_null<UserData*>, crl::time> _typing;
|
||||||
base::flat_map<not_null<UserData*>, crl::time> _speaking;
|
base::flat_map<not_null<UserData*>, crl::time> _speaking;
|
||||||
base::flat_map<not_null<UserData*>, Api::SendProgress> _sendActions;
|
base::flat_map<not_null<UserData*>, Api::SendProgress> _sendActions;
|
||||||
|
@ -62,6 +63,9 @@ private:
|
||||||
Ui::SendActionAnimation _sendActionAnimation;
|
Ui::SendActionAnimation _sendActionAnimation;
|
||||||
Ui::SendActionAnimation _speakingAnimation;
|
Ui::SendActionAnimation _speakingAnimation;
|
||||||
|
|
||||||
|
int _animationLeft = 0;
|
||||||
|
int _spacesCount = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
|
@ -303,6 +303,7 @@ void Instance::reset(const Language &data) {
|
||||||
_values[i] = GetOriginalValue(ushort(i));
|
_values[i] = GetOriginalValue(ushort(i));
|
||||||
}
|
}
|
||||||
ranges::fill(_nonDefaultSet, 0);
|
ranges::fill(_nonDefaultSet, 0);
|
||||||
|
updateSupportChoosingStickerReplacement();
|
||||||
|
|
||||||
_idChanges.fire_copy(_id);
|
_idChanges.fire_copy(_id);
|
||||||
}
|
}
|
||||||
|
@ -548,6 +549,7 @@ void Instance::fillFromSerialized(
|
||||||
applyValue(nonDefaultStrings[i], nonDefaultStrings[i + 1]);
|
applyValue(nonDefaultStrings[i], nonDefaultStrings[i + 1]);
|
||||||
}
|
}
|
||||||
updatePluralRules();
|
updatePluralRules();
|
||||||
|
updateSupportChoosingStickerReplacement();
|
||||||
|
|
||||||
_idChanges.fire_copy(_id);
|
_idChanges.fire_copy(_id);
|
||||||
}
|
}
|
||||||
|
@ -572,6 +574,7 @@ void Instance::fillFromCustomContent(
|
||||||
_pluralId = PluralCodeForCustom(absolutePath, relativePath);
|
_pluralId = PluralCodeForCustom(absolutePath, relativePath);
|
||||||
_name = _nativeName = QString();
|
_name = _nativeName = QString();
|
||||||
loadFromCustomContent(absolutePath, relativePath, content);
|
loadFromCustomContent(absolutePath, relativePath, content);
|
||||||
|
updateSupportChoosingStickerReplacement();
|
||||||
|
|
||||||
_idChanges.fire_copy(_id);
|
_idChanges.fire_copy(_id);
|
||||||
}
|
}
|
||||||
|
@ -602,6 +605,20 @@ bool Instance::loadFromCustomFile(const QString &filePath) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Instance::updateSupportChoosingStickerReplacement() {
|
||||||
|
// A language changing in the runtime is not supported.
|
||||||
|
const auto phrase = tr::lng_send_action_choose_sticker(tr::now);
|
||||||
|
const auto first = phrase.indexOf(kChoosingStickerReplacement.utf8());
|
||||||
|
const auto last = phrase.lastIndexOf(kChoosingStickerReplacement.utf8());
|
||||||
|
_supportChoosingStickerReplacement = (first == last)
|
||||||
|
? (first != -1)
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Instance::supportChoosingStickerReplacement() const {
|
||||||
|
return _supportChoosingStickerReplacement;
|
||||||
|
}
|
||||||
|
|
||||||
// SetCallback takes two QByteArrays: key, value.
|
// SetCallback takes two QByteArrays: key, value.
|
||||||
// It is called for all key-value pairs in string.
|
// It is called for all key-value pairs in string.
|
||||||
// ResetCallback takes one QByteArray: key.
|
// ResetCallback takes one QByteArray: key.
|
||||||
|
|
|
@ -13,6 +13,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace Lang {
|
namespace Lang {
|
||||||
|
|
||||||
|
inline constexpr auto kChoosingStickerReplacement = "oo"_cs;
|
||||||
|
|
||||||
struct Language {
|
struct Language {
|
||||||
QString id;
|
QString id;
|
||||||
QString pluralId;
|
QString pluralId;
|
||||||
|
@ -74,6 +76,8 @@ public:
|
||||||
QByteArray serialize() const;
|
QByteArray serialize() const;
|
||||||
void fillFromSerialized(const QByteArray &data, int dataAppVersion);
|
void fillFromSerialized(const QByteArray &data, int dataAppVersion);
|
||||||
|
|
||||||
|
bool supportChoosingStickerReplacement() const;
|
||||||
|
|
||||||
void applyDifference(
|
void applyDifference(
|
||||||
Pack pack,
|
Pack pack,
|
||||||
const MTPDlangPackDifference &difference);
|
const MTPDlangPackDifference &difference);
|
||||||
|
@ -120,6 +124,7 @@ private:
|
||||||
const QString &relativePath,
|
const QString &relativePath,
|
||||||
const QByteArray &content);
|
const QByteArray &content);
|
||||||
void updatePluralRules();
|
void updatePluralRules();
|
||||||
|
void updateSupportChoosingStickerReplacement();
|
||||||
|
|
||||||
Instance *_derived = nullptr;
|
Instance *_derived = nullptr;
|
||||||
|
|
||||||
|
@ -132,6 +137,8 @@ private:
|
||||||
int _version = 0;
|
int _version = 0;
|
||||||
rpl::event_stream<> _updated;
|
rpl::event_stream<> _updated;
|
||||||
|
|
||||||
|
bool _supportChoosingStickerReplacement;
|
||||||
|
|
||||||
mutable QString _systemLanguage;
|
mutable QString _systemLanguage;
|
||||||
|
|
||||||
std::vector<QString> _values;
|
std::vector<QString> _values;
|
||||||
|
|
Loading…
Add table
Reference in a new issue