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