mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Typing animations from android.
This commit is contained in:
parent
2b3631f3ae
commit
8958ae0377
125 changed files with 1031 additions and 669 deletions
Binary file not shown.
Before Width: | Height: | Size: 670 B After Width: | Height: | Size: 606 B |
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
@ -952,8 +952,8 @@ void AppClass::call_handleObservables() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppClass::killDownloadSessions() {
|
void AppClass::killDownloadSessions() {
|
||||||
uint64 ms = getms(), left = MTPAckSendWaiting + MTPKillFileSessionTimeout;
|
auto ms = getms(), left = static_cast<TimeMs>(MTPAckSendWaiting) + MTPKillFileSessionTimeout;
|
||||||
for (QMap<int32, uint64>::iterator i = killDownloadSessionTimes.begin(); i != killDownloadSessionTimes.end(); ) {
|
for (auto i = killDownloadSessionTimes.begin(); i != killDownloadSessionTimes.end(); ) {
|
||||||
if (i.value() <= ms) {
|
if (i.value() <= ms) {
|
||||||
for (int j = 0; j < MTPDownloadSessionsCount; ++j) {
|
for (int j = 0; j < MTPDownloadSessionsCount; ++j) {
|
||||||
MTP::stopSession(MTP::dldDcId(i.key(), j));
|
MTP::stopSession(MTP::dldDcId(i.key(), j));
|
||||||
|
|
|
@ -169,7 +169,7 @@ public:
|
||||||
bool peerPhotoFail(PeerId peerId, const RPCError &e);
|
bool peerPhotoFail(PeerId peerId, const RPCError &e);
|
||||||
void peerClearPhoto(PeerId peer);
|
void peerClearPhoto(PeerId peer);
|
||||||
|
|
||||||
void writeUserConfigIn(uint64 ms);
|
void writeUserConfigIn(TimeMs ms);
|
||||||
|
|
||||||
void killDownloadSessionsStart(int32 dc);
|
void killDownloadSessionsStart(int32 dc);
|
||||||
void killDownloadSessionsStop(int32 dc);
|
void killDownloadSessionsStop(int32 dc);
|
||||||
|
@ -208,10 +208,10 @@ private:
|
||||||
|
|
||||||
QMap<FullMsgId, PeerId> photoUpdates;
|
QMap<FullMsgId, PeerId> photoUpdates;
|
||||||
|
|
||||||
QMap<int32, uint64> killDownloadSessionTimes;
|
QMap<int32, TimeMs> killDownloadSessionTimes;
|
||||||
SingleTimer killDownloadSessionsTimer;
|
SingleTimer killDownloadSessionsTimer;
|
||||||
|
|
||||||
uint64 _lastActionTime = 0;
|
TimeMs _lastActionTime = 0;
|
||||||
|
|
||||||
MainWindow *_window = nullptr;
|
MainWindow *_window = nullptr;
|
||||||
FileUploader *_uploader = nullptr;
|
FileUploader *_uploader = nullptr;
|
||||||
|
|
|
@ -923,7 +923,7 @@ ContactsBox::Inner::ContactData *ContactsBox::Inner::contactData(Dialogs::Row *r
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsBox::Inner::paintDialog(Painter &p, uint64 ms, PeerData *peer, ContactData *data, bool sel) {
|
void ContactsBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, ContactData *data, bool sel) {
|
||||||
UserData *user = peer->asUser();
|
UserData *user = peer->asUser();
|
||||||
|
|
||||||
if (_chat && _membersFilter == MembersFilter::Admins) {
|
if (_chat && _membersFilter == MembersFilter::Admins) {
|
||||||
|
@ -1034,7 +1034,7 @@ void ContactsBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
_time = unixtime();
|
_time = unixtime();
|
||||||
p.fillRect(r, st::contactsBg);
|
p.fillRect(r, st::contactsBg);
|
||||||
|
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
int32 yFrom = r.y(), yTo = r.y() + r.height();
|
int32 yFrom = r.y(), yTo = r.y() + r.height();
|
||||||
if (_filter.isEmpty()) {
|
if (_filter.isEmpty()) {
|
||||||
if (!_contacts->isEmpty() || !_byUsername.isEmpty()) {
|
if (!_contacts->isEmpty() || !_byUsername.isEmpty()) {
|
||||||
|
|
|
@ -233,7 +233,7 @@ private:
|
||||||
void addAdminDone(const MTPUpdates &result, mtpRequestId req);
|
void addAdminDone(const MTPUpdates &result, mtpRequestId req);
|
||||||
bool addAdminFail(const RPCError &error, mtpRequestId req);
|
bool addAdminFail(const RPCError &error, mtpRequestId req);
|
||||||
|
|
||||||
void paintDialog(Painter &p, uint64 ms, PeerData *peer, ContactData *data, bool sel);
|
void paintDialog(Painter &p, TimeMs ms, PeerData *peer, ContactData *data, bool sel);
|
||||||
void paintDisabledCheckUserpic(Painter &p, PeerData *peer, int x, int y, int outerWidth) const;
|
void paintDisabledCheckUserpic(Painter &p, PeerData *peer, int x, int y, int outerWidth) const;
|
||||||
|
|
||||||
void changeCheckState(Dialogs::Row *row);
|
void changeCheckState(Dialogs::Row *row);
|
||||||
|
|
|
@ -496,7 +496,7 @@ void ShareBox::Inner::setActive(int active) {
|
||||||
emit mustScrollTo(y, y + _rowHeight);
|
emit mustScrollTo(y, y + _rowHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareBox::Inner::paintChat(Painter &p, uint64 ms, Chat *chat, int index) {
|
void ShareBox::Inner::paintChat(Painter &p, TimeMs ms, Chat *chat, int index) {
|
||||||
auto x = _rowsLeft + qFloor((index % _columnCount) * _rowWidthReal);
|
auto x = _rowsLeft + qFloor((index % _columnCount) * _rowWidthReal);
|
||||||
auto y = _rowsTop + (index / _columnCount) * _rowHeight;
|
auto y = _rowsTop + (index / _columnCount) * _rowHeight;
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ private:
|
||||||
Text name;
|
Text name;
|
||||||
FloatAnimation nameActive;
|
FloatAnimation nameActive;
|
||||||
};
|
};
|
||||||
void paintChat(Painter &p, uint64 ms, Chat *chat, int index);
|
void paintChat(Painter &p, TimeMs ms, Chat *chat, int index);
|
||||||
void updateChat(PeerData *peer);
|
void updateChat(PeerData *peer);
|
||||||
void updateChatName(Chat *chat, PeerData *peer);
|
void updateChatName(Chat *chat, PeerData *peer);
|
||||||
void repaintChat(PeerData *peer);
|
void repaintChat(PeerData *peer);
|
||||||
|
|
|
@ -661,7 +661,7 @@ QRect StickersBox::Inner::relativeButtonRect(bool removeButton) const {
|
||||||
return QRect(buttonx, buttony, buttonw, buttonh);
|
return QRect(buttonx, buttony, buttonw, buttonh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersBox::Inner::paintRow(Painter &p, int index, uint64 ms) {
|
void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
|
||||||
auto s = _rows.at(index);
|
auto s = _rows.at(index);
|
||||||
|
|
||||||
auto xadd = 0, yadd = s->yadd.current();
|
auto xadd = 0, yadd = s->yadd.current();
|
||||||
|
@ -734,7 +734,7 @@ void StickersBox::Inner::paintRow(Painter &p, int index, uint64 ms) {
|
||||||
if (xadd || yadd) p.translate(-xadd, -yadd);
|
if (xadd || yadd) p.translate(-xadd, -yadd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersBox::Inner::paintFakeButton(Painter &p, int index, uint64 ms) {
|
void StickersBox::Inner::paintFakeButton(Painter &p, int index, TimeMs ms) {
|
||||||
auto set = _rows[index];
|
auto set = _rows[index];
|
||||||
auto removeButton = (_section == Section::Installed && !set->removed);
|
auto removeButton = (_section == Section::Installed && !set->removed);
|
||||||
auto rect = relativeButtonRect(removeButton);
|
auto rect = relativeButtonRect(removeButton);
|
||||||
|
@ -846,10 +846,10 @@ void StickersBox::Inner::mouseMoveEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersBox::Inner::onUpdateSelected() {
|
void StickersBox::Inner::onUpdateSelected() {
|
||||||
QPoint local(mapFromGlobal(_mouse));
|
auto local = mapFromGlobal(_mouse);
|
||||||
if (_dragging >= 0) {
|
if (_dragging >= 0) {
|
||||||
int32 shift = 0;
|
auto shift = 0;
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
int firstSetIndex = 0;
|
int firstSetIndex = 0;
|
||||||
if (_rows.at(firstSetIndex)->isRecentSet()) {
|
if (_rows.at(firstSetIndex)->isRecentSet()) {
|
||||||
++firstSetIndex;
|
++firstSetIndex;
|
||||||
|
@ -984,11 +984,12 @@ void StickersBox::Inner::leaveEvent(QEvent *e) {
|
||||||
onUpdateSelected();
|
onUpdateSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersBox::Inner::step_shifting(uint64 ms, bool timer) {
|
void StickersBox::Inner::step_shifting(TimeMs ms, bool timer) {
|
||||||
bool animating = false;
|
auto animating = false;
|
||||||
int32 updateMin = -1, updateMax = 0;
|
auto updateMin = -1;
|
||||||
for (int32 i = 0, l = _animStartTimes.size(); i < l; ++i) {
|
auto updateMax = 0;
|
||||||
uint64 start = _animStartTimes.at(i);
|
for (auto i = 0, l = _animStartTimes.size(); i < l; ++i) {
|
||||||
|
auto start = _animStartTimes.at(i);
|
||||||
if (start) {
|
if (start) {
|
||||||
if (updateMin < 0) updateMin = i;
|
if (updateMin < 0) updateMin = i;
|
||||||
updateMax = i;
|
updateMax = i;
|
||||||
|
|
|
@ -191,9 +191,9 @@ private:
|
||||||
QRect relativeButtonRect(bool removeButton) const;
|
QRect relativeButtonRect(bool removeButton) const;
|
||||||
void ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton);
|
void ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton);
|
||||||
|
|
||||||
void step_shifting(uint64 ms, bool timer);
|
void step_shifting(TimeMs ms, bool timer);
|
||||||
void paintRow(Painter &p, int index, uint64 ms);
|
void paintRow(Painter &p, int index, TimeMs ms);
|
||||||
void paintFakeButton(Painter &p, int index, uint64 ms);
|
void paintFakeButton(Painter &p, int index, TimeMs ms);
|
||||||
void clear();
|
void clear();
|
||||||
void setActionSel(int32 actionSel);
|
void setActionSel(int32 actionSel);
|
||||||
float64 aboveShadowOpacity() const;
|
float64 aboveShadowOpacity() const;
|
||||||
|
@ -243,8 +243,8 @@ private:
|
||||||
int countMaxNameWidth() const;
|
int countMaxNameWidth() const;
|
||||||
|
|
||||||
Rows _rows;
|
Rows _rows;
|
||||||
QList<uint64> _animStartTimes;
|
QList<TimeMs> _animStartTimes;
|
||||||
uint64 _aboveShadowFadeStart = 0;
|
TimeMs _aboveShadowFadeStart = 0;
|
||||||
anim::fvalue _aboveShadowFadeOpacity = { 0., 0. };
|
anim::fvalue _aboveShadowFadeOpacity = { 0., 0. };
|
||||||
Animation _a_shifting;
|
Animation _a_shifting;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ void SingleTimer::setTimeoutHandler(base::lambda<void()> &&handler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleTimer::adjust() {
|
void SingleTimer::adjust() {
|
||||||
uint64 n = getms(true);
|
auto n = getms(true);
|
||||||
if (isActive()) {
|
if (isActive()) {
|
||||||
if (n >= _finishing) {
|
if (n >= _finishing) {
|
||||||
start(0);
|
start(0);
|
||||||
|
@ -58,7 +58,7 @@ void SingleTimer::onTimeout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleTimer::start(int msec) {
|
void SingleTimer::start(int msec) {
|
||||||
_finishing = getms(true) + (msec < 0 ? 0 : uint64(msec));
|
_finishing = getms(true) + (msec < 0 ? 0 : msec);
|
||||||
if (!_inited && App::app()) {
|
if (!_inited && App::app()) {
|
||||||
connect(App::app(), SIGNAL(adjustSingleTimers()), this, SLOT(adjust()));
|
connect(App::app(), SIGNAL(adjustSingleTimers()), this, SLOT(adjust()));
|
||||||
_inited = true;
|
_inited = true;
|
||||||
|
|
|
@ -42,7 +42,7 @@ private slots:
|
||||||
void onTimeout();
|
void onTimeout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64 _finishing = 0;
|
TimeMs _finishing = 0;
|
||||||
bool _inited = false;
|
bool _inited = false;
|
||||||
base::lambda<void()> _handler;
|
base::lambda<void()> _handler;
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ namespace {
|
||||||
|
|
||||||
float64 _msFreq;
|
float64 _msFreq;
|
||||||
float64 _msgIdCoef;
|
float64 _msgIdCoef;
|
||||||
int64 _msStart = 0, _msAddToMsStart = 0, _msAddToUnixtime = 0;
|
TimeMs _msStart = 0, _msAddToMsStart = 0, _msAddToUnixtime = 0;
|
||||||
int32 _timeStart = 0;
|
int32 _timeStart = 0;
|
||||||
|
|
||||||
class _MsInitializer {
|
class _MsInitializer {
|
||||||
|
@ -235,7 +235,7 @@ namespace {
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
//_msFreq = 1 / 1000000.;
|
//_msFreq = 1 / 1000000.;
|
||||||
_msgIdCoef = float64(0xFFFF0000L) / 1000000000.;
|
_msgIdCoef = float64(0xFFFF0000L) / 1000000000.;
|
||||||
_msStart = 1000 * uint64(ts.tv_sec) + (uint64(ts.tv_nsec) / 1000000);
|
_msStart = 1000LL * static_cast<TimeMs>(ts.tv_sec) + (static_cast<TimeMs>(ts.tv_nsec) / 1000000LL);
|
||||||
#endif
|
#endif
|
||||||
_timeStart = myunixtime();
|
_timeStart = myunixtime();
|
||||||
srand((uint32)(_msStart & 0xFFFFFFFFL));
|
srand((uint32)(_msStart & 0xFFFFFFFFL));
|
||||||
|
@ -312,8 +312,8 @@ namespace ThirdParty {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkms() {
|
bool checkms() {
|
||||||
int64 unixms = (myunixtime() - _timeStart) * 1000LL + _msAddToUnixtime;
|
auto unixms = (myunixtime() - _timeStart) * 1000LL + _msAddToUnixtime;
|
||||||
int64 ms = int64(getms(true));
|
auto ms = getms(true);
|
||||||
if (ms > unixms + 1000LL) {
|
if (ms > unixms + 1000LL) {
|
||||||
_msAddToUnixtime = ((ms - unixms) / 1000LL) * 1000LL;
|
_msAddToUnixtime = ((ms - unixms) / 1000LL) * 1000LL;
|
||||||
} else if (unixms > ms + 1000LL) {
|
} else if (unixms > ms + 1000LL) {
|
||||||
|
@ -324,24 +324,23 @@ bool checkms() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 getms(bool checked) {
|
TimeMs getms(bool checked) {
|
||||||
_msInitialize();
|
_msInitialize();
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
LARGE_INTEGER li;
|
LARGE_INTEGER li;
|
||||||
QueryPerformanceCounter(&li);
|
QueryPerformanceCounter(&li);
|
||||||
return (uint64)((li.QuadPart - _msStart) * _msFreq) + (checked ? _msAddToMsStart : 0);
|
return ((li.QuadPart - _msStart) * _msFreq) + (checked ? _msAddToMsStart : 0LL);
|
||||||
#elif defined Q_OS_MAC
|
#elif defined Q_OS_MAC
|
||||||
uint64 msCount = mach_absolute_time();
|
auto msCount = static_cast<TimeMs>(mach_absolute_time());
|
||||||
return (uint64)((msCount - _msStart) * _msFreq) + (checked ? _msAddToMsStart : 0);
|
return ((msCount - _msStart) * _msFreq) + (checked ? _msAddToMsStart : 0LL);
|
||||||
#else
|
#else
|
||||||
timespec ts;
|
timespec ts;
|
||||||
int res = clock_gettime(CLOCK_MONOTONIC, &ts);
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
|
||||||
if (res != 0) {
|
|
||||||
LOG(("Bad clock_gettime result: %1").arg(res));
|
LOG(("Bad clock_gettime result: %1").arg(res));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint64 msCount = 1000 * uint64(ts.tv_sec) + (uint64(ts.tv_nsec) / 1000000);
|
auto msCount = 1000LL * static_cast<TimeMs>(ts.tv_sec) + (static_cast<TimeMs>(ts.tv_nsec) / 1000000LL);
|
||||||
return (uint64)(msCount - _msStart) + (checked ? _msAddToMsStart : 0);
|
return (msCount - _msStart) + (checked ? _msAddToMsStart : 0LL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,8 +220,9 @@ void finish();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using TimeMs = int64;
|
||||||
bool checkms(); // returns true if time has changed
|
bool checkms(); // returns true if time has changed
|
||||||
uint64 getms(bool checked = false);
|
TimeMs getms(bool checked = false);
|
||||||
|
|
||||||
const static uint32 _md5_block_size = 64;
|
const static uint32 _md5_block_size = 64;
|
||||||
class HashMd5 {
|
class HashMd5 {
|
||||||
|
|
|
@ -59,7 +59,7 @@ void paintRowDate(Painter &p, const QDateTime &date, QRect &rectForName, bool ac
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename PaintItemCallback>
|
template <typename PaintItemCallback>
|
||||||
void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draft, QDateTime date, int w, bool active, bool selected, bool onlyBackground, PaintItemCallback paintItemCallback) {
|
void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draft, QDateTime date, int w, bool active, bool selected, bool onlyBackground, TimeMs ms, PaintItemCallback paintItemCallback) {
|
||||||
QRect fullRect(0, 0, w, st::dialogsRowHeight);
|
QRect fullRect(0, 0, w, st::dialogsRowHeight);
|
||||||
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
|
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
|
||||||
if (onlyBackground) return;
|
if (onlyBackground) return;
|
||||||
|
@ -81,7 +81,8 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf
|
||||||
paintRowDate(p, date, rectForName, active, selected);
|
paintRowDate(p, date, rectForName, active, selected);
|
||||||
|
|
||||||
p.setFont(st::dialogsTextFont);
|
p.setFont(st::dialogsTextFont);
|
||||||
if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
|
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
|
||||||
|
if (!history->paintSendAction(p, nameleft, texttop, namewidth, w, color, ms)) {
|
||||||
if (history->cloudDraftTextCache.isEmpty()) {
|
if (history->cloudDraftTextCache.isEmpty()) {
|
||||||
auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft)));
|
auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft)));
|
||||||
auto draftText = lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, textClean(draft->textWithTags.text));
|
auto draftText = lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, textClean(draft->textWithTags.text));
|
||||||
|
@ -91,17 +92,13 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf
|
||||||
textstyleSet(&(active ? st::dialogsTextStyleDraftActive : (selected ? st::dialogsTextStyleDraftOver : st::dialogsTextStyleDraft)));
|
textstyleSet(&(active ? st::dialogsTextStyleDraftActive : (selected ? st::dialogsTextStyleDraftOver : st::dialogsTextStyleDraft)));
|
||||||
history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, 1);
|
history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, 1);
|
||||||
textstyleRestore();
|
textstyleRestore();
|
||||||
} else {
|
|
||||||
p.setPen(active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService));
|
|
||||||
history->typingText.drawElided(p, nameleft, texttop, namewidth);
|
|
||||||
}
|
}
|
||||||
} else if (!item) {
|
} else if (!item) {
|
||||||
|
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
|
||||||
p.setFont(st::dialogsTextFont);
|
p.setFont(st::dialogsTextFont);
|
||||||
p.setPen(active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService));
|
if (!history->paintSendAction(p, nameleft, texttop, namewidth, w, color, ms)) {
|
||||||
if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
|
p.setPen(color);
|
||||||
p.drawText(nameleft, texttop + st::msgNameFont->ascent, lang(lng_empty_history));
|
p.drawText(nameleft, texttop + st::msgNameFont->ascent, lang(lng_empty_history));
|
||||||
} else {
|
|
||||||
history->typingText.drawElided(p, nameleft, texttop, namewidth);
|
|
||||||
}
|
}
|
||||||
} else if (!item->isEmpty()) {
|
} else if (!item->isEmpty()) {
|
||||||
paintRowDate(p, date, rectForName, active, selected);
|
paintRowDate(p, date, rectForName, active, selected);
|
||||||
|
@ -244,7 +241,7 @@ void paintUnreadCount(Painter &p, const QString &text, int x, int y, const Unrea
|
||||||
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + textTop + st.font->ascent, text);
|
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + textTop + st.font->ascent, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground) {
|
void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground, TimeMs ms) {
|
||||||
auto history = row->history();
|
auto history = row->history();
|
||||||
auto item = history->lastMsg;
|
auto item = history->lastMsg;
|
||||||
auto cloudDraft = history->cloudDraft();
|
auto cloudDraft = history->cloudDraft();
|
||||||
|
@ -270,7 +267,7 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
|
||||||
if (item && cloudDraft && unreadCount > 0) {
|
if (item && cloudDraft && unreadCount > 0) {
|
||||||
cloudDraft = nullptr; // Draw item, if draft is older.
|
cloudDraft = nullptr; // Draw item, if draft is older.
|
||||||
}
|
}
|
||||||
paintRow(p, history, item, cloudDraft, displayDate(), w, active, selected, onlyBackground, [&p, w, active, selected, history, unreadCount](int nameleft, int namewidth, HistoryItem *item) {
|
paintRow(p, history, item, cloudDraft, displayDate(), w, active, selected, onlyBackground, ms, [&p, w, active, selected, ms, history, unreadCount](int nameleft, int namewidth, HistoryItem *item) {
|
||||||
int availableWidth = namewidth;
|
int availableWidth = namewidth;
|
||||||
int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
||||||
if (unreadCount) {
|
if (unreadCount) {
|
||||||
|
@ -286,19 +283,17 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
|
||||||
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
|
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
|
||||||
availableWidth -= unreadWidth + st.padding;
|
availableWidth -= unreadWidth + st.padding;
|
||||||
}
|
}
|
||||||
if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
|
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
|
||||||
|
if (!history->paintSendAction(p, nameleft, texttop, availableWidth, w, color, ms)) {
|
||||||
item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dialogsTextFont->height), active, selected, history->textCachedFor, history->lastItemTextCache);
|
item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dialogsTextFont->height), active, selected, history->textCachedFor, history->lastItemTextCache);
|
||||||
} else {
|
|
||||||
p.setPen(active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService));
|
|
||||||
history->typingText.drawElided(p, nameleft, texttop, availableWidth);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RowPainter::paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground) {
|
void RowPainter::paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground, TimeMs ms) {
|
||||||
auto item = row->item();
|
auto item = row->item();
|
||||||
auto history = item->history();
|
auto history = item->history();
|
||||||
paintRow(p, history, item, nullptr, item->date, w, active, selected, onlyBackground, [&p, row, active, selected](int nameleft, int namewidth, HistoryItem *item) {
|
paintRow(p, history, item, nullptr, item->date, w, active, selected, onlyBackground, ms, [&p, row, active, selected](int nameleft, int namewidth, HistoryItem *item) {
|
||||||
int lastWidth = namewidth, texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
int lastWidth = namewidth, texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
||||||
item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, selected, row->_cacheFor, row->_cache);
|
item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, selected, row->_cacheFor, row->_cache);
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,8 +31,8 @@ const style::icon *ChatTypeIcon(PeerData *peer, bool active, bool selected);
|
||||||
|
|
||||||
class RowPainter {
|
class RowPainter {
|
||||||
public:
|
public:
|
||||||
static void paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground);
|
static void paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground, TimeMs ms);
|
||||||
static void paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground);
|
static void paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground, TimeMs ms);
|
||||||
};
|
};
|
||||||
|
|
||||||
void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool onlyBackground);
|
void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool onlyBackground);
|
||||||
|
|
|
@ -47,7 +47,7 @@ void List::adjustCurrent(int32 y, int32 h) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void List::paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel, bool onlyBackground) const {
|
void List::paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel, bool onlyBackground, TimeMs ms) const {
|
||||||
adjustCurrent(hFrom, st::dialogsRowHeight);
|
adjustCurrent(hFrom, st::dialogsRowHeight);
|
||||||
|
|
||||||
Row *row = _current;
|
Row *row = _current;
|
||||||
|
@ -55,7 +55,7 @@ void List::paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, Pee
|
||||||
while (row != _end && row->_pos * st::dialogsRowHeight < hTo) {
|
while (row != _end && row->_pos * st::dialogsRowHeight < hTo) {
|
||||||
bool active = (row->history()->peer == act) || (row->history()->peer->migrateTo() && row->history()->peer->migrateTo() == act);
|
bool active = (row->history()->peer == act) || (row->history()->peer->migrateTo() && row->history()->peer->migrateTo() == act);
|
||||||
bool selected = (row->history()->peer == sel);
|
bool selected = (row->history()->peer == sel);
|
||||||
Layout::RowPainter::paint(p, row, w, active, selected, onlyBackground);
|
Layout::RowPainter::paint(p, row, w, active, selected, onlyBackground, ms);
|
||||||
row = row->_next;
|
row = row->_next;
|
||||||
p.translate(0, st::dialogsRowHeight);
|
p.translate(0, st::dialogsRowHeight);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
return *i;
|
return *i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel, bool onlyBackground) const;
|
void paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel, bool onlyBackground, TimeMs ms) const;
|
||||||
Row *addToEnd(History *history);
|
Row *addToEnd(History *history);
|
||||||
Row *adjustByName(const PeerData *peer);
|
Row *adjustByName(const PeerData *peer);
|
||||||
Row *addByName(History *history);
|
Row *addByName(History *history);
|
||||||
|
|
|
@ -96,7 +96,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
if (!paintingOther) {
|
if (!paintingOther) {
|
||||||
p.setClipRect(r);
|
p.setClipRect(r);
|
||||||
}
|
}
|
||||||
|
auto ms = paintingOther ? TimeMs(0) : getms();
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
QRect dialogsClip = r;
|
QRect dialogsClip = r;
|
||||||
if (importantDialogs) {
|
if (importantDialogs) {
|
||||||
|
@ -105,9 +105,9 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
p.translate(0, st::dialogsImportantBarHeight);
|
p.translate(0, st::dialogsImportantBarHeight);
|
||||||
}
|
}
|
||||||
int32 otherStart = shownDialogs()->size() * st::dialogsRowHeight;
|
int32 otherStart = shownDialogs()->size() * st::dialogsRowHeight;
|
||||||
PeerData *active = App::main()->activePeer(), *selected = _menuPeer ? _menuPeer : (_sel ? _sel->history()->peer : 0);
|
auto active = App::main()->activePeer(), selected = _menuPeer ? _menuPeer : (_sel ? _sel->history()->peer : nullptr);
|
||||||
if (otherStart) {
|
if (otherStart) {
|
||||||
shownDialogs()->all().paint(p, fullWidth(), dialogsClip.top(), dialogsClip.top() + dialogsClip.height(), active, selected, paintingOther);
|
shownDialogs()->all().paint(p, fullWidth(), dialogsClip.top(), dialogsClip.top() + dialogsClip.height(), active, selected, paintingOther, ms);
|
||||||
}
|
}
|
||||||
if (!otherStart) {
|
if (!otherStart) {
|
||||||
p.fillRect(dialogsClip, st::dialogsBg);
|
p.fillRect(dialogsClip, st::dialogsBg);
|
||||||
|
@ -171,7 +171,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
for (; from < to; ++from) {
|
for (; from < to; ++from) {
|
||||||
bool active = ((_filterResults[from]->history()->peer == act) || (_filterResults[from]->history()->peer->migrateTo() && _filterResults[from]->history()->peer->migrateTo() == act)) && !actId;
|
bool active = ((_filterResults[from]->history()->peer == act) || (_filterResults[from]->history()->peer->migrateTo() && _filterResults[from]->history()->peer->migrateTo() == act)) && !actId;
|
||||||
bool selected = (from == _filteredSel) || (_filterResults[from]->history()->peer == _menuPeer);
|
bool selected = (from == _filteredSel) || (_filterResults[from]->history()->peer == _menuPeer);
|
||||||
Dialogs::Layout::RowPainter::paint(p, _filterResults[from], w, active, selected, paintingOther);
|
Dialogs::Layout::RowPainter::paint(p, _filterResults[from], w, active, selected, paintingOther, ms);
|
||||||
p.translate(0, st::dialogsRowHeight);
|
p.translate(0, st::dialogsRowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
auto history = item->history();
|
auto history = item->history();
|
||||||
bool active = (history->peer == act && item->id == actId) || (history->peer->migrateTo() && history->peer->migrateTo() == act && item->id == -actId);
|
bool active = (history->peer == act && item->id == actId) || (history->peer->migrateTo() && history->peer->migrateTo() == act && item->id == -actId);
|
||||||
bool selected = (from == _searchedSel);
|
bool selected = (from == _searchedSel);
|
||||||
Dialogs::Layout::RowPainter::paint(p, result, w, active, selected, paintingOther);
|
Dialogs::Layout::RowPainter::paint(p, result, w, active, selected, paintingOther, ms);
|
||||||
p.translate(0, st::dialogsRowHeight);
|
p.translate(0, st::dialogsRowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ signals:
|
||||||
void refreshHashtags();
|
void refreshHashtags();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintRegion(Painter &p, const QRegion ®ion, bool paintingOther);
|
void paintRegion(Painter &p, const QRegion ®ion, bool paintingOther) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void itemRemoved(HistoryItem *item);
|
void itemRemoved(HistoryItem *item);
|
||||||
|
|
|
@ -633,12 +633,12 @@ struct Data {
|
||||||
|
|
||||||
Stickers::Sets StickerSets;
|
Stickers::Sets StickerSets;
|
||||||
Stickers::Order StickerSetsOrder;
|
Stickers::Order StickerSetsOrder;
|
||||||
uint64 LastStickersUpdate = 0;
|
TimeMs LastStickersUpdate = 0;
|
||||||
uint64 LastRecentStickersUpdate = 0;
|
TimeMs LastRecentStickersUpdate = 0;
|
||||||
Stickers::Order FeaturedStickerSetsOrder;
|
Stickers::Order FeaturedStickerSetsOrder;
|
||||||
int FeaturedStickerSetsUnreadCount = 0;
|
int FeaturedStickerSetsUnreadCount = 0;
|
||||||
base::Observable<void> FeaturedStickerSetsUnreadCountChanged;
|
base::Observable<void> FeaturedStickerSetsUnreadCountChanged;
|
||||||
uint64 LastFeaturedStickersUpdate = 0;
|
TimeMs LastFeaturedStickersUpdate = 0;
|
||||||
Stickers::Order ArchivedStickerSetsOrder;
|
Stickers::Order ArchivedStickerSetsOrder;
|
||||||
|
|
||||||
MTP::DcOptions DcOptions;
|
MTP::DcOptions DcOptions;
|
||||||
|
@ -751,12 +751,12 @@ DefineRefVar(Global, PendingItemsMap, PendingRepaintItems);
|
||||||
|
|
||||||
DefineVar(Global, Stickers::Sets, StickerSets);
|
DefineVar(Global, Stickers::Sets, StickerSets);
|
||||||
DefineVar(Global, Stickers::Order, StickerSetsOrder);
|
DefineVar(Global, Stickers::Order, StickerSetsOrder);
|
||||||
DefineVar(Global, uint64, LastStickersUpdate);
|
DefineVar(Global, TimeMs, LastStickersUpdate);
|
||||||
DefineVar(Global, uint64, LastRecentStickersUpdate);
|
DefineVar(Global, TimeMs, LastRecentStickersUpdate);
|
||||||
DefineVar(Global, Stickers::Order, FeaturedStickerSetsOrder);
|
DefineVar(Global, Stickers::Order, FeaturedStickerSetsOrder);
|
||||||
DefineVar(Global, int, FeaturedStickerSetsUnreadCount);
|
DefineVar(Global, int, FeaturedStickerSetsUnreadCount);
|
||||||
DefineRefVar(Global, base::Observable<void>, FeaturedStickerSetsUnreadCountChanged);
|
DefineRefVar(Global, base::Observable<void>, FeaturedStickerSetsUnreadCountChanged);
|
||||||
DefineVar(Global, uint64, LastFeaturedStickersUpdate);
|
DefineVar(Global, TimeMs, LastFeaturedStickersUpdate);
|
||||||
DefineVar(Global, Stickers::Order, ArchivedStickerSetsOrder);
|
DefineVar(Global, Stickers::Order, ArchivedStickerSetsOrder);
|
||||||
|
|
||||||
DefineVar(Global, MTP::DcOptions, DcOptions);
|
DefineVar(Global, MTP::DcOptions, DcOptions);
|
||||||
|
|
|
@ -313,12 +313,12 @@ DeclareRefVar(PendingItemsMap, PendingRepaintItems);
|
||||||
|
|
||||||
DeclareVar(Stickers::Sets, StickerSets);
|
DeclareVar(Stickers::Sets, StickerSets);
|
||||||
DeclareVar(Stickers::Order, StickerSetsOrder);
|
DeclareVar(Stickers::Order, StickerSetsOrder);
|
||||||
DeclareVar(uint64, LastStickersUpdate);
|
DeclareVar(TimeMs, LastStickersUpdate);
|
||||||
DeclareVar(uint64, LastRecentStickersUpdate);
|
DeclareVar(TimeMs, LastRecentStickersUpdate);
|
||||||
DeclareVar(Stickers::Order, FeaturedStickerSetsOrder);
|
DeclareVar(Stickers::Order, FeaturedStickerSetsOrder);
|
||||||
DeclareVar(int, FeaturedStickerSetsUnreadCount);
|
DeclareVar(int, FeaturedStickerSetsUnreadCount);
|
||||||
DeclareRefVar(base::Observable<void>, FeaturedStickerSetsUnreadCountChanged);
|
DeclareRefVar(base::Observable<void>, FeaturedStickerSetsUnreadCountChanged);
|
||||||
DeclareVar(uint64, LastFeaturedStickersUpdate);
|
DeclareVar(TimeMs, LastFeaturedStickersUpdate);
|
||||||
DeclareVar(Stickers::Order, ArchivedStickerSetsOrder);
|
DeclareVar(Stickers::Order, ArchivedStickerSetsOrder);
|
||||||
|
|
||||||
DeclareVar(MTP::DcOptions, DcOptions);
|
DeclareVar(MTP::DcOptions, DcOptions);
|
||||||
|
|
|
@ -34,6 +34,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr int kStatusShowClientsideTyping = 6000;
|
||||||
constexpr int kStatusShowClientsideRecordVideo = 6000;
|
constexpr int kStatusShowClientsideRecordVideo = 6000;
|
||||||
constexpr int kStatusShowClientsideUploadVideo = 6000;
|
constexpr int kStatusShowClientsideUploadVideo = 6000;
|
||||||
constexpr int kStatusShowClientsideRecordVoice = 6000;
|
constexpr int kStatusShowClientsideRecordVoice = 6000;
|
||||||
|
@ -43,6 +44,7 @@ constexpr int kStatusShowClientsideUploadFile = 6000;
|
||||||
constexpr int kStatusShowClientsideChooseLocation = 6000;
|
constexpr int kStatusShowClientsideChooseLocation = 6000;
|
||||||
constexpr int kStatusShowClientsideChooseContact = 6000;
|
constexpr int kStatusShowClientsideChooseContact = 6000;
|
||||||
constexpr int kStatusShowClientsidePlayGame = 10000;
|
constexpr int kStatusShowClientsidePlayGame = 10000;
|
||||||
|
constexpr int kSetMyActionForMs = 10000;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -54,7 +56,7 @@ void historyInit() {
|
||||||
History::History(const PeerId &peerId)
|
History::History(const PeerId &peerId)
|
||||||
: peer(App::peer(peerId))
|
: peer(App::peer(peerId))
|
||||||
, lastItemTextCache(st::dialogsTextWidthMin)
|
, lastItemTextCache(st::dialogsTextWidthMin)
|
||||||
, typingText(st::dialogsTextWidthMin)
|
, _sendActionText(st::dialogsTextWidthMin)
|
||||||
, cloudDraftTextCache(st::dialogsTextWidthMin)
|
, cloudDraftTextCache(st::dialogsTextWidthMin)
|
||||||
, _mute(isNotifyMuted(peer->notify)) {
|
, _mute(isNotifyMuted(peer->notify)) {
|
||||||
if (peer->isUser() && peer->asUser()->botInfo) {
|
if (peer->isUser() && peer->asUser()->botInfo) {
|
||||||
|
@ -183,87 +185,165 @@ void History::draftSavedToCloud() {
|
||||||
if (App::main()) App::main()->writeDrafts(this);
|
if (App::main()) App::main()->writeDrafts(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool History::updateTyping(uint64 ms, bool force) {
|
bool History::updateSendActionNeedsAnimating(UserData *user, const MTPSendMessageAction &action) {
|
||||||
bool changed = force;
|
using Type = SendAction::Type;
|
||||||
for (auto i = typing.begin(), e = typing.end(); i != e;) {
|
if (action.type() == mtpc_sendMessageCancelAction) {
|
||||||
|
unregSendAction(user);
|
||||||
|
return false;
|
||||||
|
} else if (action.type() == mtpc_sendMessageGameStopAction) {
|
||||||
|
auto it = _sendActions.find(user);
|
||||||
|
if (it != _sendActions.end() && it->type == Type::PlayGame) {
|
||||||
|
unregSendAction(user);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ms = getms();
|
||||||
|
switch (action.type()) {
|
||||||
|
case mtpc_sendMessageTypingAction: _typing.insert(user, ms + kStatusShowClientsideTyping); break;
|
||||||
|
case mtpc_sendMessageRecordVideoAction: _sendActions.insert(user, { Type::RecordVideo, ms + kStatusShowClientsideRecordVideo }); break;
|
||||||
|
case mtpc_sendMessageUploadVideoAction: _sendActions.insert(user, { Type::UploadVideo, ms + kStatusShowClientsideUploadVideo, action.c_sendMessageUploadVideoAction().vprogress.v }); break;
|
||||||
|
case mtpc_sendMessageRecordAudioAction: _sendActions.insert(user, { Type::RecordVoice, ms + kStatusShowClientsideRecordVoice }); break;
|
||||||
|
case mtpc_sendMessageUploadAudioAction: _sendActions.insert(user, { Type::UploadVoice, ms + kStatusShowClientsideUploadVoice, action.c_sendMessageUploadAudioAction().vprogress.v }); break;
|
||||||
|
case mtpc_sendMessageUploadPhotoAction: _sendActions.insert(user, { Type::UploadPhoto, ms + kStatusShowClientsideUploadPhoto, action.c_sendMessageUploadPhotoAction().vprogress.v }); break;
|
||||||
|
case mtpc_sendMessageUploadDocumentAction: _sendActions.insert(user, { Type::UploadFile, ms + kStatusShowClientsideUploadFile, action.c_sendMessageUploadDocumentAction().vprogress.v }); break;
|
||||||
|
case mtpc_sendMessageGeoLocationAction: _sendActions.insert(user, { Type::ChooseLocation, ms + kStatusShowClientsideChooseLocation }); break;
|
||||||
|
case mtpc_sendMessageChooseContactAction: _sendActions.insert(user, { Type::ChooseContact, ms + kStatusShowClientsideChooseContact }); break;
|
||||||
|
case mtpc_sendMessageGamePlayAction: {
|
||||||
|
auto it = _sendActions.find(user);
|
||||||
|
if (it == _sendActions.end() || it->type == Type::PlayGame || it->until <= ms) {
|
||||||
|
_sendActions.insert(user, { Type::PlayGame, ms + kStatusShowClientsidePlayGame });
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
return updateSendActionNeedsAnimating(ms, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool History::mySendActionUpdated(SendAction::Type type, bool doing) {
|
||||||
|
auto ms = getms(true);
|
||||||
|
auto i = _mySendActions.find(type);
|
||||||
|
if (doing) {
|
||||||
|
if (i == _mySendActions.cend()) {
|
||||||
|
_mySendActions.insert(type, ms + kSetMyActionForMs);
|
||||||
|
} else if (i.value() > ms + (kSetMyActionForMs / 2)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
i.value() = ms + kSetMyActionForMs;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (i == _mySendActions.cend()) {
|
||||||
|
return false;
|
||||||
|
} else if (i.value() <= ms) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
_mySendActions.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool History::paintSendAction(Painter &p, int x, int y, int availableWidth, int outerWidth, const style::color &color, TimeMs ms) {
|
||||||
|
if (_sendActionAnimation) {
|
||||||
|
_sendActionAnimation.paint(p, color, x, y + st::normalFont->ascent, outerWidth, ms);
|
||||||
|
auto animationWidth = _sendActionAnimation.width();
|
||||||
|
x += animationWidth;
|
||||||
|
availableWidth -= animationWidth;
|
||||||
|
p.setPen(color);
|
||||||
|
_sendActionText.drawElided(p, x, y, availableWidth);
|
||||||
|
updateSendActionAnimationAreas();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool History::updateSendActionNeedsAnimating(TimeMs ms, bool force) {
|
||||||
|
auto changed = force;
|
||||||
|
for (auto i = _typing.begin(), e = _typing.end(); i != e;) {
|
||||||
if (ms >= i.value()) {
|
if (ms >= i.value()) {
|
||||||
i = typing.erase(i);
|
i = _typing.erase(i);
|
||||||
changed = true;
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto i = sendActions.begin(); i != sendActions.cend();) {
|
for (auto i = _sendActions.begin(); i != _sendActions.cend();) {
|
||||||
if (ms >= i.value().until) {
|
if (ms >= i.value().until) {
|
||||||
i = sendActions.erase(i);
|
i = _sendActions.erase(i);
|
||||||
changed = true;
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
QString newTypingStr;
|
QString newTypingString;
|
||||||
int typingCount = typing.size();
|
auto typingCount = _typing.size();
|
||||||
if (typingCount > 2) {
|
if (typingCount > 2) {
|
||||||
newTypingStr = lng_many_typing(lt_count, typingCount);
|
newTypingString = lng_many_typing(lt_count, typingCount);
|
||||||
} else if (typingCount > 1) {
|
} else if (typingCount > 1) {
|
||||||
newTypingStr = lng_users_typing(lt_user, typing.begin().key()->firstName, lt_second_user, (typing.end() - 1).key()->firstName);
|
newTypingString = lng_users_typing(lt_user, _typing.begin().key()->firstName, lt_second_user, (_typing.end() - 1).key()->firstName);
|
||||||
} else if (typingCount) {
|
} else if (typingCount) {
|
||||||
newTypingStr = peer->isUser() ? lang(lng_typing) : lng_user_typing(lt_user, typing.begin().key()->firstName);
|
newTypingString = peer->isUser() ? lang(lng_typing) : lng_user_typing(lt_user, _typing.begin().key()->firstName);
|
||||||
} else if (!sendActions.isEmpty()) {
|
} else if (!_sendActions.isEmpty()) {
|
||||||
// Handles all actions except game playing.
|
// Handles all actions except game playing.
|
||||||
auto sendActionString = [](SendActionType type, const QString &name) -> QString {
|
using Type = SendAction::Type;
|
||||||
|
auto sendActionString = [](Type type, const QString &name) -> QString {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SendActionRecordVideo: return name.isEmpty() ? lang(lng_send_action_record_video) : lng_user_action_record_video(lt_user, name);
|
case Type::RecordVideo: return name.isEmpty() ? lang(lng_send_action_record_video) : lng_user_action_record_video(lt_user, name);
|
||||||
case SendActionUploadVideo: return name.isEmpty() ? lang(lng_send_action_upload_video) : lng_user_action_upload_video(lt_user, name);
|
case Type::UploadVideo: return name.isEmpty() ? lang(lng_send_action_upload_video) : lng_user_action_upload_video(lt_user, name);
|
||||||
case SendActionRecordVoice: return name.isEmpty() ? lang(lng_send_action_record_audio) : lng_user_action_record_audio(lt_user, name);
|
case Type::RecordVoice: return name.isEmpty() ? lang(lng_send_action_record_audio) : lng_user_action_record_audio(lt_user, name);
|
||||||
case SendActionUploadVoice: return name.isEmpty() ? lang(lng_send_action_upload_audio) : lng_user_action_upload_audio(lt_user, name);
|
case Type::UploadVoice: return name.isEmpty() ? lang(lng_send_action_upload_audio) : lng_user_action_upload_audio(lt_user, name);
|
||||||
case SendActionUploadPhoto: return name.isEmpty() ? lang(lng_send_action_upload_photo) : lng_user_action_upload_photo(lt_user, name);
|
case Type::UploadPhoto: return name.isEmpty() ? lang(lng_send_action_upload_photo) : lng_user_action_upload_photo(lt_user, name);
|
||||||
case SendActionUploadFile: return name.isEmpty() ? lang(lng_send_action_upload_file) : lng_user_action_upload_file(lt_user, name);
|
case Type::UploadFile: return name.isEmpty() ? lang(lng_send_action_upload_file) : lng_user_action_upload_file(lt_user, name);
|
||||||
case SendActionChooseLocation: return name.isEmpty() ? lang(lng_send_action_geo_location) : lng_user_action_geo_location(lt_user, name);
|
case Type::ChooseLocation: return name.isEmpty() ? lang(lng_send_action_geo_location) : lng_user_action_geo_location(lt_user, name);
|
||||||
case SendActionChooseContact: return name.isEmpty() ? lang(lng_send_action_choose_contact) : lng_user_action_choose_contact(lt_user, name);
|
case Type::ChooseContact: return name.isEmpty() ? lang(lng_send_action_choose_contact) : lng_user_action_choose_contact(lt_user, name);
|
||||||
default: break;
|
default: break;
|
||||||
};
|
};
|
||||||
return QString();
|
return QString();
|
||||||
};
|
};
|
||||||
for (auto i = sendActions.cbegin(), e = sendActions.cend(); i != e; ++i) {
|
for (auto i = _sendActions.cbegin(), e = _sendActions.cend(); i != e; ++i) {
|
||||||
newTypingStr = sendActionString(i->type, peer->isUser() ? QString() : i.key()->firstName);
|
newTypingString = sendActionString(i->type, peer->isUser() ? QString() : i.key()->firstName);
|
||||||
if (!newTypingStr.isEmpty()) {
|
if (!newTypingString.isEmpty()) {
|
||||||
|
_sendActionAnimation.start(i->type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everyone in sendActions are playing a game.
|
// Everyone in sendActions are playing a game.
|
||||||
if (newTypingStr.isEmpty()) {
|
if (newTypingString.isEmpty()) {
|
||||||
int playingCount = sendActions.size();
|
int playingCount = _sendActions.size();
|
||||||
if (playingCount > 2) {
|
if (playingCount > 2) {
|
||||||
newTypingStr = lng_many_playing_game(lt_count, playingCount);
|
newTypingString = lng_many_playing_game(lt_count, playingCount);
|
||||||
} else if (playingCount > 1) {
|
} else if (playingCount > 1) {
|
||||||
newTypingStr = lng_users_playing_game(lt_user, sendActions.begin().key()->firstName, lt_second_user, (sendActions.end() - 1).key()->firstName);
|
newTypingString = lng_users_playing_game(lt_user, _sendActions.begin().key()->firstName, lt_second_user, (_sendActions.end() - 1).key()->firstName);
|
||||||
} else {
|
} else {
|
||||||
newTypingStr = peer->isUser() ? lang(lng_playing_game) : lng_user_playing_game(lt_user, sendActions.begin().key()->firstName);
|
newTypingString = peer->isUser() ? lang(lng_playing_game) : lng_user_playing_game(lt_user, _sendActions.begin().key()->firstName);
|
||||||
|
}
|
||||||
|
_sendActionAnimation.start(Type::PlayGame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (typingCount > 0) {
|
||||||
|
_sendActionAnimation.start(SendAction::Type::Typing);
|
||||||
|
} else if (newTypingString.isEmpty()) {
|
||||||
|
_sendActionAnimation.stop();
|
||||||
}
|
}
|
||||||
if (!newTypingStr.isEmpty()) {
|
if (_sendActionString != newTypingString) {
|
||||||
newTypingStr += qsl("...");
|
_sendActionString = newTypingString;
|
||||||
}
|
_sendActionText.setText(st::dialogsTextFont, _sendActionString, _textNameOptions);
|
||||||
if (typingStr != newTypingStr) {
|
|
||||||
typingText.setText(st::dialogsTextFont, (typingStr = newTypingStr), _textNameOptions);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!typingStr.isEmpty()) {
|
auto result = (!_typing.isEmpty() || !_sendActions.isEmpty());
|
||||||
if (typingText.lastDots(typingDots % 4)) {
|
if (changed || result) {
|
||||||
changed = true;
|
updateSendActionAnimationAreas();
|
||||||
}
|
}
|
||||||
}
|
return result;
|
||||||
if (changed && App::main()) {
|
}
|
||||||
|
|
||||||
|
void History::updateSendActionAnimationAreas() {
|
||||||
updateChatListEntry();
|
updateChatListEntry();
|
||||||
if (App::main()->historyPeer() == peer) {
|
if (App::main()->historyPeer() == peer) {
|
||||||
App::main()->topBar()->update();
|
App::main()->topBar()->update();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelHistory::ChannelHistory(const PeerId &peer) : History(peer)
|
ChannelHistory::ChannelHistory(const PeerId &peer) : History(peer)
|
||||||
|
@ -561,56 +641,23 @@ void Histories::clear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Histories::regSendAction(History *history, UserData *user, const MTPSendMessageAction &action, TimeId when) {
|
void Histories::regSendAction(History *history, UserData *user, const MTPSendMessageAction &action, TimeId when) {
|
||||||
if (action.type() == mtpc_sendMessageCancelAction) {
|
if (history->updateSendActionNeedsAnimating(user, action)) {
|
||||||
history->unregTyping(user);
|
|
||||||
return;
|
|
||||||
} else if (action.type() == mtpc_sendMessageGameStopAction) {
|
|
||||||
auto it = history->sendActions.find(user);
|
|
||||||
if (it != history->sendActions.end() && it->type == SendActionPlayGame) {
|
|
||||||
history->unregTyping(user);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 ms = getms();
|
|
||||||
switch (action.type()) {
|
|
||||||
case mtpc_sendMessageTypingAction: history->typing[user] = ms + 6000; break;
|
|
||||||
case mtpc_sendMessageRecordVideoAction: history->sendActions.insert(user, SendAction(SendActionRecordVideo, ms + kStatusShowClientsideRecordVideo)); break;
|
|
||||||
case mtpc_sendMessageUploadVideoAction: history->sendActions.insert(user, SendAction(SendActionUploadVideo, ms + kStatusShowClientsideUploadVideo, action.c_sendMessageUploadVideoAction().vprogress.v)); break;
|
|
||||||
case mtpc_sendMessageRecordAudioAction: history->sendActions.insert(user, SendAction(SendActionRecordVoice, ms + kStatusShowClientsideRecordVoice)); break;
|
|
||||||
case mtpc_sendMessageUploadAudioAction: history->sendActions.insert(user, SendAction(SendActionUploadVoice, ms + kStatusShowClientsideUploadVoice, action.c_sendMessageUploadAudioAction().vprogress.v)); break;
|
|
||||||
case mtpc_sendMessageUploadPhotoAction: history->sendActions.insert(user, SendAction(SendActionUploadPhoto, ms + kStatusShowClientsideUploadPhoto, action.c_sendMessageUploadPhotoAction().vprogress.v)); break;
|
|
||||||
case mtpc_sendMessageUploadDocumentAction: history->sendActions.insert(user, SendAction(SendActionUploadFile, ms + kStatusShowClientsideUploadFile, action.c_sendMessageUploadDocumentAction().vprogress.v)); break;
|
|
||||||
case mtpc_sendMessageGeoLocationAction: history->sendActions.insert(user, SendAction(SendActionChooseLocation, ms + kStatusShowClientsideChooseLocation)); break;
|
|
||||||
case mtpc_sendMessageChooseContactAction: history->sendActions.insert(user, SendAction(SendActionChooseContact, ms + kStatusShowClientsideChooseContact)); break;
|
|
||||||
case mtpc_sendMessageGamePlayAction: {
|
|
||||||
auto it = history->sendActions.find(user);
|
|
||||||
if (it == history->sendActions.end() || it->type == SendActionPlayGame || it->until <= ms) {
|
|
||||||
history->sendActions.insert(user, SendAction(SendActionPlayGame, ms + kStatusShowClientsidePlayGame));
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
default: return;
|
|
||||||
}
|
|
||||||
|
|
||||||
user->madeAction(when);
|
user->madeAction(when);
|
||||||
|
|
||||||
auto i = typing.find(history);
|
auto i = typing.find(history);
|
||||||
if (i == typing.cend()) {
|
if (i == typing.cend()) {
|
||||||
typing.insert(history, ms);
|
typing.insert(history, getms());
|
||||||
history->typingDots = 0;
|
|
||||||
_a_typings.start();
|
_a_typings.start();
|
||||||
}
|
}
|
||||||
history->updateTyping(ms, true);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Histories::step_typings(uint64 ms, bool timer) {
|
void Histories::step_typings(TimeMs ms, bool timer) {
|
||||||
for (TypingHistories::iterator i = typing.begin(), e = typing.end(); i != e;) {
|
for (auto i = typing.begin(), e = typing.end(); i != e;) {
|
||||||
i.key()->typingDots = (ms - i.value()) / 150;
|
if (i.key()->updateSendActionNeedsAnimating(ms)) {
|
||||||
i.key()->updateTyping(ms);
|
|
||||||
if (i.key()->typing.isEmpty() && i.key()->sendActions.isEmpty()) {
|
|
||||||
i = typing.erase(i);
|
|
||||||
} else {
|
|
||||||
++i;
|
++i;
|
||||||
|
} else {
|
||||||
|
i = typing.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typing.isEmpty()) {
|
if (typing.isEmpty()) {
|
||||||
|
@ -1107,20 +1154,20 @@ HistoryItem *History::addNewItem(HistoryItem *adding, bool newMsg) {
|
||||||
return adding;
|
return adding;
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::unregTyping(UserData *from) {
|
void History::unregSendAction(UserData *from) {
|
||||||
uint64 updateAtMs = 0;
|
auto updateAtMs = TimeMs(0);
|
||||||
auto i = typing.find(from);
|
auto i = _typing.find(from);
|
||||||
if (i != typing.cend()) {
|
if (i != _typing.cend()) {
|
||||||
updateAtMs = getms();
|
updateAtMs = getms();
|
||||||
i.value() = updateAtMs;
|
i.value() = updateAtMs;
|
||||||
}
|
}
|
||||||
auto j = sendActions.find(from);
|
auto j = _sendActions.find(from);
|
||||||
if (j != sendActions.cend()) {
|
if (j != _sendActions.cend()) {
|
||||||
if (!updateAtMs) updateAtMs = getms();
|
if (!updateAtMs) updateAtMs = getms();
|
||||||
j.value().until = updateAtMs;
|
j.value().until = updateAtMs;
|
||||||
}
|
}
|
||||||
if (updateAtMs) {
|
if (updateAtMs) {
|
||||||
updateTyping(updateAtMs, true);
|
updateSendActionNeedsAnimating(updateAtMs, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1128,7 +1175,7 @@ void History::newItemAdded(HistoryItem *item) {
|
||||||
App::checkImageCacheSize();
|
App::checkImageCacheSize();
|
||||||
if (item->from() && item->from()->isUser()) {
|
if (item->from() && item->from()->isUser()) {
|
||||||
if (item->from() == item->author()) {
|
if (item->from() == item->author()) {
|
||||||
unregTyping(item->from()->asUser());
|
unregSendAction(item->from()->asUser());
|
||||||
}
|
}
|
||||||
MTPint itemServerTime;
|
MTPint itemServerTime;
|
||||||
toServerTime(item->date.toTime_t(), itemServerTime);
|
toServerTime(item->date.toTime_t(), itemServerTime);
|
||||||
|
|
|
@ -20,14 +20,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "structs.h"
|
||||||
|
#include "dialogs/dialogs_common.h"
|
||||||
|
#include "ui/effects/send_action_animations.h"
|
||||||
|
|
||||||
void historyInit();
|
void historyInit();
|
||||||
|
|
||||||
class HistoryItem;
|
class HistoryItem;
|
||||||
|
using SelectedItemSet = QMap<int32, HistoryItem*>;
|
||||||
typedef QMap<int32, HistoryItem*> SelectedItemSet;
|
|
||||||
|
|
||||||
#include "structs.h"
|
|
||||||
#include "dialogs/dialogs_common.h"
|
|
||||||
|
|
||||||
enum NewMessageType {
|
enum NewMessageType {
|
||||||
NewMessageUnread,
|
NewMessageUnread,
|
||||||
|
@ -45,7 +45,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void regSendAction(History *history, UserData *user, const MTPSendMessageAction &action, TimeId when);
|
void regSendAction(History *history, UserData *user, const MTPSendMessageAction &action, TimeId when);
|
||||||
void step_typings(uint64 ms, bool timer);
|
void step_typings(TimeMs ms, bool timer);
|
||||||
|
|
||||||
History *find(const PeerId &peerId);
|
History *find(const PeerId &peerId);
|
||||||
History *findOrInsert(const PeerId &peerId);
|
History *findOrInsert(const PeerId &peerId);
|
||||||
|
@ -59,7 +59,7 @@ public:
|
||||||
|
|
||||||
HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type);
|
HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type);
|
||||||
|
|
||||||
typedef QMap<History*, uint64> TypingHistories; // when typing in this history started
|
typedef QMap<History*, TimeMs> TypingHistories; // when typing in this history started
|
||||||
TypingHistories typing;
|
TypingHistories typing;
|
||||||
Animation _a_typings;
|
Animation _a_typings;
|
||||||
|
|
||||||
|
@ -132,26 +132,6 @@ inline MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
|
||||||
return MTPMessagesFilter();
|
return MTPMessagesFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SendActionType {
|
|
||||||
SendActionTyping,
|
|
||||||
SendActionRecordVideo,
|
|
||||||
SendActionUploadVideo,
|
|
||||||
SendActionRecordVoice,
|
|
||||||
SendActionUploadVoice,
|
|
||||||
SendActionUploadPhoto,
|
|
||||||
SendActionUploadFile,
|
|
||||||
SendActionChooseLocation,
|
|
||||||
SendActionChooseContact,
|
|
||||||
SendActionPlayGame,
|
|
||||||
};
|
|
||||||
struct SendAction {
|
|
||||||
SendAction(SendActionType type, uint64 until, int32 progress = 0) : type(type), until(until), progress(progress) {
|
|
||||||
}
|
|
||||||
SendActionType type;
|
|
||||||
uint64 until;
|
|
||||||
int32 progress;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TextWithTags {
|
struct TextWithTags {
|
||||||
struct Tag {
|
struct Tag {
|
||||||
int offset, length;
|
int offset, length;
|
||||||
|
@ -237,7 +217,6 @@ public:
|
||||||
void eraseFromOverview(MediaOverviewType type, MsgId msgId);
|
void eraseFromOverview(MediaOverviewType type, MsgId msgId);
|
||||||
|
|
||||||
void newItemAdded(HistoryItem *item);
|
void newItemAdded(HistoryItem *item);
|
||||||
void unregTyping(UserData *from);
|
|
||||||
|
|
||||||
int countUnread(MsgId upTo);
|
int countUnread(MsgId upTo);
|
||||||
void updateShowFrom();
|
void updateShowFrom();
|
||||||
|
@ -332,7 +311,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void paintDialog(Painter &p, int32 w, bool sel) const;
|
void paintDialog(Painter &p, int32 w, bool sel) const;
|
||||||
bool updateTyping(uint64 ms, bool force = false);
|
bool updateSendActionNeedsAnimating(TimeMs ms, bool force = false);
|
||||||
|
void unregSendAction(UserData *from);
|
||||||
|
bool updateSendActionNeedsAnimating(UserData *user, const MTPSendMessageAction &action);
|
||||||
|
void updateSendActionAnimationAreas();
|
||||||
|
bool mySendActionUpdated(SendAction::Type type, bool doing);
|
||||||
|
bool paintSendAction(Painter &p, int x, int y, int availableWidth, int outerWidth, const style::color &color, TimeMs ms);
|
||||||
|
|
||||||
void clearLastKeyboard();
|
void clearLastKeyboard();
|
||||||
|
|
||||||
// optimization for userpics displayed on the left
|
// optimization for userpics displayed on the left
|
||||||
|
@ -425,15 +410,6 @@ public:
|
||||||
mutable const HistoryItem *textCachedFor = nullptr; // cache
|
mutable const HistoryItem *textCachedFor = nullptr; // cache
|
||||||
mutable Text lastItemTextCache;
|
mutable Text lastItemTextCache;
|
||||||
|
|
||||||
using TypingUsers = QMap<UserData*, uint64>;
|
|
||||||
TypingUsers typing;
|
|
||||||
using SendActionUsers = QMap<UserData*, SendAction>;
|
|
||||||
SendActionUsers sendActions;
|
|
||||||
QString typingStr;
|
|
||||||
Text typingText;
|
|
||||||
uint32 typingDots;
|
|
||||||
QMap<SendActionType, uint64> mySendActions;
|
|
||||||
|
|
||||||
typedef QList<MsgId> MediaOverview;
|
typedef QList<MsgId> MediaOverview;
|
||||||
MediaOverview overview[OverviewCount];
|
MediaOverview overview[OverviewCount];
|
||||||
|
|
||||||
|
@ -569,6 +545,16 @@ private:
|
||||||
std_::unique_ptr<Data::Draft> _localDraft, _cloudDraft;
|
std_::unique_ptr<Data::Draft> _localDraft, _cloudDraft;
|
||||||
std_::unique_ptr<Data::Draft> _editDraft;
|
std_::unique_ptr<Data::Draft> _editDraft;
|
||||||
|
|
||||||
|
using TypingUsers = QMap<UserData*, TimeMs>;
|
||||||
|
TypingUsers _typing;
|
||||||
|
using SendActionUsers = QMap<UserData*, SendAction>;
|
||||||
|
SendActionUsers _sendActions;
|
||||||
|
QString _sendActionString;
|
||||||
|
Text _sendActionText;
|
||||||
|
Ui::SendActionAnimation _sendActionAnimation;
|
||||||
|
QMap<SendAction::Type, TimeMs> _mySendActions;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class HistoryJoined;
|
class HistoryJoined;
|
||||||
|
|
|
@ -222,7 +222,7 @@ int ReplyKeyboard::naturalHeight() const {
|
||||||
return (_rows.size() - 1) * _st->buttonSkip() + _rows.size() * _st->buttonHeight();
|
return (_rows.size() - 1) * _st->buttonSkip() + _rows.size() * _st->buttonHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplyKeyboard::paint(Painter &p, int outerWidth, const QRect &clip, uint64 ms) const {
|
void ReplyKeyboard::paint(Painter &p, int outerWidth, const QRect &clip, TimeMs ms) const {
|
||||||
t_assert(_st != nullptr);
|
t_assert(_st != nullptr);
|
||||||
t_assert(_width > 0);
|
t_assert(_width > 0);
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ void ReplyKeyboard::startAnimation(int i, int j, int direction) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplyKeyboard::step_selected(uint64 ms, bool timer) {
|
void ReplyKeyboard::step_selected(TimeMs ms, bool timer) {
|
||||||
for (Animations::iterator i = _animations.begin(); i != _animations.end();) {
|
for (Animations::iterator i = _animations.begin(); i != _animations.end();) {
|
||||||
int index = qAbs(i.key()) - 1, row = (index / MatrixRowShift), col = index % MatrixRowShift;
|
int index = qAbs(i.key()) - 1, row = (index / MatrixRowShift), col = index % MatrixRowShift;
|
||||||
float64 dt = float64(ms - i.value()) / st::botKbDuration;
|
float64 dt = float64(ms - i.value()) / st::botKbDuration;
|
||||||
|
@ -361,7 +361,7 @@ int ReplyKeyboard::Style::buttonHeight() const {
|
||||||
return _st->height;
|
return _st->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplyKeyboard::Style::paintButton(Painter &p, int outerWidth, const ReplyKeyboard::Button &button, uint64 ms) const {
|
void ReplyKeyboard::Style::paintButton(Painter &p, int outerWidth, const ReplyKeyboard::Button &button, TimeMs ms) const {
|
||||||
const QRect &rect = button.rect;
|
const QRect &rect = button.rect;
|
||||||
paintButtonBg(p, rect, button.howMuchOver);
|
paintButtonBg(p, rect, button.howMuchOver);
|
||||||
if (button.ripple) {
|
if (button.ripple) {
|
||||||
|
|
|
@ -314,7 +314,7 @@ public:
|
||||||
private:
|
private:
|
||||||
const style::BotKeyboardButton *_st;
|
const style::BotKeyboardButton *_st;
|
||||||
|
|
||||||
void paintButton(Painter &p, int outerWidth, const ReplyKeyboard::Button &button, uint64 ms) const;
|
void paintButton(Painter &p, int outerWidth, const ReplyKeyboard::Button &button, TimeMs ms) const;
|
||||||
friend class ReplyKeyboard;
|
friend class ReplyKeyboard;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -332,7 +332,7 @@ public:
|
||||||
int naturalWidth() const;
|
int naturalWidth() const;
|
||||||
int naturalHeight() const;
|
int naturalHeight() const;
|
||||||
|
|
||||||
void paint(Painter &p, int outerWidth, const QRect &clip, uint64 ms) const;
|
void paint(Painter &p, int outerWidth, const QRect &clip, TimeMs ms) const;
|
||||||
ClickHandlerPtr getState(int x, int y) const;
|
ClickHandlerPtr getState(int x, int y) const;
|
||||||
|
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active);
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active);
|
||||||
|
@ -363,8 +363,8 @@ private:
|
||||||
};
|
};
|
||||||
ButtonCoords findButtonCoordsByClickHandler(const ClickHandlerPtr &p);
|
ButtonCoords findButtonCoordsByClickHandler(const ClickHandlerPtr &p);
|
||||||
|
|
||||||
using Animations = QMap<int, uint64>;
|
using Animations = QMap<int, TimeMs>;
|
||||||
void step_selected(uint64 ms, bool timer);
|
void step_selected(TimeMs ms, bool timer);
|
||||||
|
|
||||||
const HistoryItem *_item;
|
const HistoryItem *_item;
|
||||||
int _width = 0;
|
int _width = 0;
|
||||||
|
@ -473,7 +473,7 @@ public:
|
||||||
}
|
}
|
||||||
return resizeGetHeight_(width);
|
return resizeGetHeight_(width);
|
||||||
}
|
}
|
||||||
virtual void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const = 0;
|
virtual void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const = 0;
|
||||||
|
|
||||||
virtual void dependencyItemRemoved(HistoryItem *dependency) {
|
virtual void dependencyItemRemoved(HistoryItem *dependency) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
_width = qMin(width, _maxw);
|
_width = qMin(width, _maxw);
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
virtual void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const = 0;
|
virtual void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const = 0;
|
||||||
virtual HistoryTextState getState(int x, int y, HistoryStateRequest request) const = 0;
|
virtual HistoryTextState getState(int x, int y, HistoryStateRequest request) const = 0;
|
||||||
|
|
||||||
// if we are in selecting items mode perhaps we want to
|
// if we are in selecting items mode perhaps we want to
|
||||||
|
|
|
@ -203,7 +203,7 @@ void HistoryFileMedia::step_thumbOver(float64 ms, bool timer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryFileMedia::step_radial(uint64 ms, bool timer) {
|
void HistoryFileMedia::step_radial(TimeMs ms, bool timer) {
|
||||||
if (timer) {
|
if (timer) {
|
||||||
Ui::repaintHistoryItem(_parent);
|
Ui::repaintHistoryItem(_parent);
|
||||||
} else {
|
} else {
|
||||||
|
@ -356,7 +356,7 @@ int HistoryPhoto::resizeGetHeight(int width) {
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||||
|
|
||||||
_data->automaticLoad(_parent);
|
_data->automaticLoad(_parent);
|
||||||
|
@ -703,7 +703,7 @@ int HistoryVideo::resizeGetHeight(int width) {
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||||
|
|
||||||
_data->automaticLoad(_parent);
|
_data->automaticLoad(_parent);
|
||||||
|
@ -1064,7 +1064,7 @@ int HistoryDocument::resizeGetHeight(int width) {
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||||
|
|
||||||
_data->automaticLoad(_parent);
|
_data->automaticLoad(_parent);
|
||||||
|
@ -1671,7 +1671,7 @@ int HistoryGif::resizeGetHeight(int width) {
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||||
|
|
||||||
_data->automaticLoad(_parent);
|
_data->automaticLoad(_parent);
|
||||||
|
@ -2001,7 +2001,7 @@ int HistorySticker::resizeGetHeight(int width) { // return new height
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
auto sticker = _data->sticker();
|
auto sticker = _data->sticker();
|
||||||
if (!sticker) return;
|
if (!sticker) return;
|
||||||
|
|
||||||
|
@ -2270,7 +2270,7 @@ void HistoryContact::initDimensions() {
|
||||||
_height = _minh;
|
_height = _minh;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||||
int32 skipx = 0, skipy = 0, width = _width, height = _height;
|
int32 skipx = 0, skipy = 0, width = _width, height = _height;
|
||||||
|
|
||||||
|
@ -2643,7 +2643,7 @@ int HistoryWebPage::resizeGetHeight(int width) {
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||||
int32 skipx = 0, skipy = 0, width = _width, height = _height;
|
int32 skipx = 0, skipy = 0, width = _width, height = _height;
|
||||||
|
|
||||||
|
@ -3042,7 +3042,7 @@ int HistoryGame::resizeGetHeight(int width) {
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryGame::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistoryGame::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||||
int32 width = _width, height = _height;
|
int32 width = _width, height = _height;
|
||||||
|
|
||||||
|
@ -3367,7 +3367,7 @@ int HistoryLocation::resizeGetHeight(int width) {
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryLocation::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistoryLocation::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||||
int32 skipx = 0, skipy = 0, width = _width, height = _height;
|
int32 skipx = 0, skipy = 0, width = _width, height = _height;
|
||||||
bool bubble = _parent->hasBubble();
|
bool bubble = _parent->hasBubble();
|
||||||
|
|
|
@ -72,18 +72,18 @@ protected:
|
||||||
void setStatusSize(int32 newSize, int32 fullSize, int32 duration, qint64 realDuration) const;
|
void setStatusSize(int32 newSize, int32 fullSize, int32 duration, qint64 realDuration) const;
|
||||||
|
|
||||||
void step_thumbOver(float64 ms, bool timer);
|
void step_thumbOver(float64 ms, bool timer);
|
||||||
void step_radial(uint64 ms, bool timer);
|
void step_radial(TimeMs ms, bool timer);
|
||||||
|
|
||||||
void ensureAnimation() const;
|
void ensureAnimation() const;
|
||||||
void checkAnimationFinished();
|
void checkAnimationFinished();
|
||||||
|
|
||||||
bool isRadialAnimation(uint64 ms) const {
|
bool isRadialAnimation(TimeMs ms) const {
|
||||||
if (!_animation || !_animation->radial.animating()) return false;
|
if (!_animation || !_animation->radial.animating()) return false;
|
||||||
|
|
||||||
_animation->radial.step(ms);
|
_animation->radial.step(ms);
|
||||||
return _animation && _animation->radial.animating();
|
return _animation && _animation->radial.animating();
|
||||||
}
|
}
|
||||||
bool isThumbAnimation(uint64 ms) const {
|
bool isThumbAnimation(TimeMs ms) const {
|
||||||
if (!_animation || !_animation->_a_thumbOver.animating()) return false;
|
if (!_animation || !_animation->_a_thumbOver.animating()) return false;
|
||||||
|
|
||||||
_animation->_a_thumbOver.step(ms);
|
_animation->_a_thumbOver.step(ms);
|
||||||
|
@ -125,7 +125,7 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int resizeGetHeight(int width) override;
|
int resizeGetHeight(int width) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override {
|
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override {
|
||||||
|
@ -212,7 +212,7 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int resizeGetHeight(int width) override;
|
int resizeGetHeight(int width) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override {
|
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override {
|
||||||
|
@ -336,7 +336,7 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int resizeGetHeight(int width) override;
|
int resizeGetHeight(int width) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override {
|
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override {
|
||||||
|
@ -433,7 +433,7 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int resizeGetHeight(int width) override;
|
int resizeGetHeight(int width) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override {
|
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override {
|
||||||
|
@ -530,7 +530,7 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int resizeGetHeight(int width) override;
|
int resizeGetHeight(int width) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
|
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
|
||||||
|
@ -593,7 +593,7 @@ public:
|
||||||
|
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
|
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
|
||||||
|
@ -656,7 +656,7 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int resizeGetHeight(int width) override;
|
int resizeGetHeight(int width) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override;
|
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override;
|
||||||
|
@ -756,7 +756,7 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int resizeGetHeight(int width) override;
|
int resizeGetHeight(int width) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override;
|
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override;
|
||||||
|
@ -859,7 +859,7 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int resizeGetHeight(int32 width) override;
|
int resizeGetHeight(int32 width) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override;
|
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override;
|
||||||
|
|
|
@ -1236,7 +1236,7 @@ void HistoryMessage::setId(MsgId newId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessage::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistoryMessage::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
bool outbg = out() && !isPost(), bubble = drawBubble(), selected = (selection == FullSelection);
|
bool outbg = out() && !isPost(), bubble = drawBubble(), selected = (selection == FullSelection);
|
||||||
|
|
||||||
int left = 0, width = 0, height = _height;
|
int left = 0, width = 0, height = _height;
|
||||||
|
@ -1256,7 +1256,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, TextSelection selection, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 fullAnimMs = App::main() ? App::main()->animActiveTimeStart(this) : 0;
|
auto fullAnimMs = App::main() ? App::main()->animActiveTimeStart(this) : 0LL;
|
||||||
if (fullAnimMs > 0 && fullAnimMs <= ms) {
|
if (fullAnimMs > 0 && fullAnimMs <= ms) {
|
||||||
int animms = ms - fullAnimMs;
|
int animms = ms - fullAnimMs;
|
||||||
if (animms > st::activeFadeInDuration + st::activeFadeOutDuration) {
|
if (animms > st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||||
|
@ -2111,7 +2111,7 @@ void HistoryService::setServiceText(const QString &text, const Links &links) {
|
||||||
_textHeight = 0;
|
_textHeight = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryService::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
|
void HistoryService::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
|
||||||
int height = _height - st::msgServiceMargin.top() - st::msgServiceMargin.bottom();
|
int height = _height - st::msgServiceMargin.top() - st::msgServiceMargin.bottom();
|
||||||
|
|
||||||
QRect clip(r);
|
QRect clip(r);
|
||||||
|
|
|
@ -71,7 +71,7 @@ public:
|
||||||
void drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const override;
|
void drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const override;
|
||||||
void setViewsCount(int32 count) override;
|
void setViewsCount(int32 count) override;
|
||||||
void setId(MsgId newId) override;
|
void setId(MsgId newId) override;
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
|
|
||||||
void dependencyItemRemoved(HistoryItem *dependency) override;
|
void dependencyItemRemoved(HistoryItem *dependency) override;
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ public:
|
||||||
|
|
||||||
void countPositionAndSize(int32 &left, int32 &width) const;
|
void countPositionAndSize(int32 &left, int32 &width) const;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
bool hasPoint(int x, int y) const override;
|
bool hasPoint(int x, int y) const override;
|
||||||
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ void ServiceMessagePainter::paint(Painter &p, const HistoryService *message, con
|
||||||
message->countPositionAndSize(left, width);
|
message->countPositionAndSize(left, width);
|
||||||
if (width < 1) return;
|
if (width < 1) return;
|
||||||
|
|
||||||
uint64 fullAnimMs = App::main() ? App::main()->animActiveTimeStart(message) : 0;
|
auto fullAnimMs = App::main() ? App::main()->animActiveTimeStart(message) : 0LL;
|
||||||
if (fullAnimMs > 0 && fullAnimMs <= context.ms) {
|
if (fullAnimMs > 0 && fullAnimMs <= context.ms) {
|
||||||
int animms = context.ms - fullAnimMs;
|
int animms = context.ms - fullAnimMs;
|
||||||
if (animms > st::activeFadeInDuration + st::activeFadeOutDuration) {
|
if (animms > st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||||
|
|
|
@ -23,12 +23,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
namespace HistoryLayout {
|
namespace HistoryLayout {
|
||||||
|
|
||||||
struct PaintContext {
|
struct PaintContext {
|
||||||
PaintContext(uint64 ms, const QRect &clip, TextSelection selection)
|
PaintContext(TimeMs ms, const QRect &clip, TextSelection selection)
|
||||||
: ms(ms)
|
: ms(ms)
|
||||||
, clip(clip)
|
, clip(clip)
|
||||||
, selection(selection) {
|
, selection(selection) {
|
||||||
}
|
}
|
||||||
uint64 ms;
|
TimeMs ms;
|
||||||
const QRect &clip;
|
const QRect &clip;
|
||||||
TextSelection selection;
|
TextSelection selection;
|
||||||
};
|
};
|
||||||
|
|
|
@ -409,7 +409,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
if (!trivial) {
|
if (!trivial) {
|
||||||
p.setClipRect(r);
|
p.setClipRect(r);
|
||||||
}
|
}
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
|
|
||||||
bool historyDisplayedEmpty = (_history->isDisplayedEmpty() && (!_migrated || _migrated->isDisplayedEmpty()));
|
bool historyDisplayedEmpty = (_history->isDisplayedEmpty() && (!_migrated || _migrated->isDisplayedEmpty()));
|
||||||
bool noHistoryDisplayed = _firstLoading || historyDisplayedEmpty;
|
bool noHistoryDisplayed = _firstLoading || historyDisplayedEmpty;
|
||||||
|
@ -612,7 +612,7 @@ bool HistoryInner::event(QEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::onTouchScrollTimer() {
|
void HistoryInner::onTouchScrollTimer() {
|
||||||
uint64 nowTime = getms();
|
auto nowTime = getms();
|
||||||
if (_touchScrollState == Ui::TouchScrollState::Acceleration && _touchWaitingAcceleration && (nowTime - _touchAccelerationTime) > 40) {
|
if (_touchScrollState == Ui::TouchScrollState::Acceleration && _touchWaitingAcceleration && (nowTime - _touchAccelerationTime) > 40) {
|
||||||
_touchScrollState = Ui::TouchScrollState::Manual;
|
_touchScrollState = Ui::TouchScrollState::Manual;
|
||||||
touchResetSpeed();
|
touchResetSpeed();
|
||||||
|
@ -633,7 +633,7 @@ void HistoryInner::onTouchScrollTimer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::touchUpdateSpeed() {
|
void HistoryInner::touchUpdateSpeed() {
|
||||||
const uint64 nowTime = getms();
|
const auto nowTime = getms();
|
||||||
if (_touchPrevPosValid) {
|
if (_touchPrevPosValid) {
|
||||||
const int elapsed = nowTime - _touchSpeedTime;
|
const int elapsed = nowTime - _touchSpeedTime;
|
||||||
if (elapsed) {
|
if (elapsed) {
|
||||||
|
@ -3296,7 +3296,7 @@ void HistoryWidget::onTextChange() {
|
||||||
|
|
||||||
if (_peer && (!_peer->isChannel() || _peer->isMegagroup())) {
|
if (_peer && (!_peer->isChannel() || _peer->isMegagroup())) {
|
||||||
if (!_inlineBot && !_editMsgId && (_textUpdateEvents.testFlag(TextUpdateEvent::SendTyping))) {
|
if (!_inlineBot && !_editMsgId && (_textUpdateEvents.testFlag(TextUpdateEvent::SendTyping))) {
|
||||||
updateSendAction(_history, SendActionTyping);
|
updateSendAction(_history, SendAction::Type::Typing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3345,7 +3345,7 @@ void HistoryWidget::onDraftSaveDelayed() {
|
||||||
void HistoryWidget::onDraftSave(bool delayed) {
|
void HistoryWidget::onDraftSave(bool delayed) {
|
||||||
if (!_peer) return;
|
if (!_peer) return;
|
||||||
if (delayed) {
|
if (delayed) {
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
if (!_saveDraftStart) {
|
if (!_saveDraftStart) {
|
||||||
_saveDraftStart = ms;
|
_saveDraftStart = ms;
|
||||||
return _saveDraftTimer.start(SaveDraftTimeout);
|
return _saveDraftTimer.start(SaveDraftTimeout);
|
||||||
|
@ -3435,8 +3435,8 @@ void HistoryWidget::writeDrafts(Data::Draft **localDraft, Data::Draft **editDraf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::cancelSendAction(History *history, SendActionType type) {
|
void HistoryWidget::cancelSendAction(History *history, SendAction::Type type) {
|
||||||
QMap<QPair<History*, SendActionType>, mtpRequestId>::iterator i = _sendActionRequests.find(qMakePair(history, type));
|
auto i = _sendActionRequests.find(qMakePair(history, type));
|
||||||
if (i != _sendActionRequests.cend()) {
|
if (i != _sendActionRequests.cend()) {
|
||||||
MTP::cancel(i.value());
|
MTP::cancel(i.value());
|
||||||
_sendActionRequests.erase(i);
|
_sendActionRequests.erase(i);
|
||||||
|
@ -3444,46 +3444,33 @@ void HistoryWidget::cancelSendAction(History *history, SendActionType type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onCancelSendAction() {
|
void HistoryWidget::onCancelSendAction() {
|
||||||
cancelSendAction(_history, SendActionTyping);
|
cancelSendAction(_history, SendAction::Type::Typing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateSendAction(History *history, SendActionType type, int32 progress) {
|
void HistoryWidget::updateSendAction(History *history, SendAction::Type type, int32 progress) {
|
||||||
if (!history) return;
|
if (!history) return;
|
||||||
|
|
||||||
bool doing = (progress >= 0);
|
auto doing = (progress >= 0);
|
||||||
|
if (history->mySendActionUpdated(type, doing)) {
|
||||||
uint64 ms = getms(true) + 10000;
|
|
||||||
QMap<SendActionType, uint64>::iterator i = history->mySendActions.find(type);
|
|
||||||
if (doing && i != history->mySendActions.cend() && i.value() + 5000 > ms) return;
|
|
||||||
if (!doing && (i == history->mySendActions.cend() || i.value() + 5000 <= ms)) return;
|
|
||||||
|
|
||||||
if (doing) {
|
|
||||||
if (i == history->mySendActions.cend()) {
|
|
||||||
history->mySendActions.insert(type, ms);
|
|
||||||
} else {
|
|
||||||
i.value() = ms;
|
|
||||||
}
|
|
||||||
} else if (i != history->mySendActions.cend()) {
|
|
||||||
history->mySendActions.erase(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelSendAction(history, type);
|
cancelSendAction(history, type);
|
||||||
if (doing) {
|
if (doing) {
|
||||||
|
using Type = SendAction::Type;
|
||||||
MTPsendMessageAction action;
|
MTPsendMessageAction action;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SendActionTyping: action = MTP_sendMessageTypingAction(); break;
|
case Type::Typing: action = MTP_sendMessageTypingAction(); break;
|
||||||
case SendActionRecordVideo: action = MTP_sendMessageRecordVideoAction(); break;
|
case Type::RecordVideo: action = MTP_sendMessageRecordVideoAction(); break;
|
||||||
case SendActionUploadVideo: action = MTP_sendMessageUploadVideoAction(MTP_int(progress)); break;
|
case Type::UploadVideo: action = MTP_sendMessageUploadVideoAction(MTP_int(progress)); break;
|
||||||
case SendActionRecordVoice: action = MTP_sendMessageRecordAudioAction(); break;
|
case Type::RecordVoice: action = MTP_sendMessageRecordAudioAction(); break;
|
||||||
case SendActionUploadVoice: action = MTP_sendMessageUploadAudioAction(MTP_int(progress)); break;
|
case Type::UploadVoice: action = MTP_sendMessageUploadAudioAction(MTP_int(progress)); break;
|
||||||
case SendActionUploadPhoto: action = MTP_sendMessageUploadPhotoAction(MTP_int(progress)); break;
|
case Type::UploadPhoto: action = MTP_sendMessageUploadPhotoAction(MTP_int(progress)); break;
|
||||||
case SendActionUploadFile: action = MTP_sendMessageUploadDocumentAction(MTP_int(progress)); break;
|
case Type::UploadFile: action = MTP_sendMessageUploadDocumentAction(MTP_int(progress)); break;
|
||||||
case SendActionChooseLocation: action = MTP_sendMessageGeoLocationAction(); break;
|
case Type::ChooseLocation: action = MTP_sendMessageGeoLocationAction(); break;
|
||||||
case SendActionChooseContact: action = MTP_sendMessageChooseContactAction(); break;
|
case Type::ChooseContact: action = MTP_sendMessageChooseContactAction(); break;
|
||||||
case SendActionPlayGame: action = MTP_sendMessageGamePlayAction(); break;
|
case Type::PlayGame: action = MTP_sendMessageGamePlayAction(); break;
|
||||||
}
|
}
|
||||||
_sendActionRequests.insert(qMakePair(history, type), MTP::send(MTPmessages_SetTyping(history->peer->input, action), rpcDone(&HistoryWidget::sendActionDone)));
|
_sendActionRequests.insert(qMakePair(history, type), MTP::send(MTPmessages_SetTyping(history->peer->input, action), rpcDone(&HistoryWidget::sendActionDone)));
|
||||||
if (type == SendActionTyping) _sendActionStopTimer.start(5000);
|
if (type == Type::Typing) _sendActionStopTimer.start(5000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3496,7 +3483,7 @@ void HistoryWidget::stickersInstalled(uint64 setId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::sendActionDone(const MTPBool &result, mtpRequestId req) {
|
void HistoryWidget::sendActionDone(const MTPBool &result, mtpRequestId req) {
|
||||||
for (QMap<QPair<History*, SendActionType>, mtpRequestId>::iterator i = _sendActionRequests.begin(), e = _sendActionRequests.end(); i != e; ++i) {
|
for (auto i = _sendActionRequests.begin(), e = _sendActionRequests.end(); i != e; ++i) {
|
||||||
if (i.value() == req) {
|
if (i.value() == req) {
|
||||||
_sendActionRequests.erase(i);
|
_sendActionRequests.erase(i);
|
||||||
break;
|
break;
|
||||||
|
@ -3555,7 +3542,7 @@ void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
|
||||||
}
|
}
|
||||||
updateField();
|
updateField();
|
||||||
if (_peer && (!_peer->isChannel() || _peer->isMegagroup())) {
|
if (_peer && (!_peer->isChannel() || _peer->isMegagroup())) {
|
||||||
updateSendAction(_history, SendActionRecordVoice);
|
updateSendAction(_history, SendAction::Type::RecordVoice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4220,9 +4207,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_history->mySendActions.contains(SendActionTyping)) {
|
updateSendAction(_history, SendAction::Type::Typing, -1);
|
||||||
updateSendAction(_history, SendActionTyping, -1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cAutoPlayGif()) {
|
if (!cAutoPlayGif()) {
|
||||||
|
@ -5715,7 +5700,7 @@ void HistoryWidget::stopRecording(bool send) {
|
||||||
_recording = false;
|
_recording = false;
|
||||||
_recordingSamples = 0;
|
_recordingSamples = 0;
|
||||||
if (_peer && (!_peer->isChannel() || _peer->isMegagroup())) {
|
if (_peer && (!_peer->isChannel() || _peer->isMegagroup())) {
|
||||||
updateSendAction(_history, SendActionRecordVoice, -1);
|
updateSendAction(_history, SendAction::Type::RecordVoice, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
|
@ -5838,7 +5823,7 @@ void HistoryWidget::botCallbackDone(BotCallbackInfo info, const MTPmessages_BotC
|
||||||
url = appendShareGameScoreUrl(url, info.msgId);
|
url = appendShareGameScoreUrl(url, info.msgId);
|
||||||
BotGameUrlClickHandler(info.bot, url).onClick(Qt::LeftButton);
|
BotGameUrlClickHandler(info.bot, url).onClick(Qt::LeftButton);
|
||||||
if (item && (!item->history()->peer->isChannel() || item->history()->peer->isMegagroup())) {
|
if (item && (!item->history()->peer->isChannel() || item->history()->peer->isMegagroup())) {
|
||||||
updateSendAction(item->history(), SendActionPlayGame);
|
updateSendAction(item->history(), SendAction::Type::PlayGame);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UrlClickHandler(url).onClick(Qt::LeftButton);
|
UrlClickHandler(url).onClick(Qt::LeftButton);
|
||||||
|
@ -6211,7 +6196,7 @@ void HistoryWidget::onForwardHere() {
|
||||||
App::forward(_peer->id, ForwardContextMessage);
|
App::forward(_peer->id, ForwardContextMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth) {
|
bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
|
||||||
if (_a_show.animating()) {
|
if (_a_show.animating()) {
|
||||||
int retina = cIntRetinaFactor();
|
int retina = cIntRetinaFactor();
|
||||||
if (a_coordOver.current() > 0) {
|
if (a_coordOver.current() > 0) {
|
||||||
|
@ -6232,12 +6217,9 @@ bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth) {
|
||||||
decreaseWidth += increaseLeft;
|
decreaseWidth += increaseLeft;
|
||||||
QRect rectForName(st::topBarArrowPadding.right() + increaseLeft, st::topBarArrowPadding.top(), width() - decreaseWidth - st::topBarArrowPadding.left() - st::topBarArrowPadding.right(), st::msgNameFont->height);
|
QRect rectForName(st::topBarArrowPadding.right() + increaseLeft, st::topBarArrowPadding.top(), width() - decreaseWidth - st::topBarArrowPadding.left() - st::topBarArrowPadding.right(), st::msgNameFont->height);
|
||||||
p.setFont(st::dialogsTextFont);
|
p.setFont(st::dialogsTextFont);
|
||||||
if (_history->typing.isEmpty() && _history->sendActions.isEmpty()) {
|
if (!_history->paintSendAction(p, rectForName.x(), st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height, rectForName.width(), width(), st::statusFgActive, ms)) {
|
||||||
p.setPen(_titlePeerTextOnline ? st::statusFgActive : st::statusFg);
|
p.setPen(_titlePeerTextOnline ? st::statusFgActive : st::statusFg);
|
||||||
p.drawText(rectForName.x(), st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height + st::dialogsTextFont->ascent, _titlePeerText);
|
p.drawText(rectForName.x(), st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height + st::dialogsTextFont->ascent, _titlePeerText);
|
||||||
} else {
|
|
||||||
p.setPen(st::statusFgTyping);
|
|
||||||
_history->typingText.drawElided(p, rectForName.x(), st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height, rectForName.width());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setPen(st::dialogsNameFg);
|
p.setPen(st::dialogsNameFg);
|
||||||
|
@ -6900,7 +6882,7 @@ void HistoryWidget::onPhotoProgress(const FullMsgId &newId) {
|
||||||
if (HistoryItem *item = App::histItemById(newId)) {
|
if (HistoryItem *item = App::histItemById(newId)) {
|
||||||
PhotoData *photo = (item->getMedia() && item->getMedia()->type() == MediaTypePhoto) ? static_cast<HistoryPhoto*>(item->getMedia())->photo() : 0;
|
PhotoData *photo = (item->getMedia() && item->getMedia()->type() == MediaTypePhoto) ? static_cast<HistoryPhoto*>(item->getMedia())->photo() : 0;
|
||||||
if (!item->isPost()) {
|
if (!item->isPost()) {
|
||||||
updateSendAction(item->history(), SendActionUploadPhoto, 0);
|
updateSendAction(item->history(), SendAction::Type::UploadPhoto, 0);
|
||||||
}
|
}
|
||||||
Ui::repaintHistoryItem(item);
|
Ui::repaintHistoryItem(item);
|
||||||
}
|
}
|
||||||
|
@ -6912,7 +6894,7 @@ void HistoryWidget::onDocumentProgress(const FullMsgId &newId) {
|
||||||
HistoryMedia *media = item->getMedia();
|
HistoryMedia *media = item->getMedia();
|
||||||
DocumentData *doc = media ? media->getDocument() : 0;
|
DocumentData *doc = media ? media->getDocument() : 0;
|
||||||
if (!item->isPost()) {
|
if (!item->isPost()) {
|
||||||
updateSendAction(item->history(), (doc && doc->voice()) ? SendActionUploadVoice : SendActionUploadFile, doc ? doc->uploadOffset : 0);
|
updateSendAction(item->history(), (doc && doc->voice()) ? SendAction::Type::UploadVoice : SendAction::Type::UploadFile, doc ? doc->uploadOffset : 0);
|
||||||
}
|
}
|
||||||
Ui::repaintHistoryItem(item);
|
Ui::repaintHistoryItem(item);
|
||||||
}
|
}
|
||||||
|
@ -6923,7 +6905,7 @@ void HistoryWidget::onPhotoFailed(const FullMsgId &newId) {
|
||||||
HistoryItem *item = App::histItemById(newId);
|
HistoryItem *item = App::histItemById(newId);
|
||||||
if (item) {
|
if (item) {
|
||||||
if (!item->isPost()) {
|
if (!item->isPost()) {
|
||||||
updateSendAction(item->history(), SendActionUploadPhoto, -1);
|
updateSendAction(item->history(), SendAction::Type::UploadPhoto, -1);
|
||||||
}
|
}
|
||||||
// Ui::repaintHistoryItem(item);
|
// Ui::repaintHistoryItem(item);
|
||||||
}
|
}
|
||||||
|
@ -6936,7 +6918,7 @@ void HistoryWidget::onDocumentFailed(const FullMsgId &newId) {
|
||||||
HistoryMedia *media = item->getMedia();
|
HistoryMedia *media = item->getMedia();
|
||||||
DocumentData *doc = media ? media->getDocument() : 0;
|
DocumentData *doc = media ? media->getDocument() : 0;
|
||||||
if (!item->isPost()) {
|
if (!item->isPost()) {
|
||||||
updateSendAction(item->history(), (doc && doc->voice()) ? SendActionUploadVoice : SendActionUploadFile, -1);
|
updateSendAction(item->history(), (doc && doc->voice()) ? SendAction::Type::UploadVoice : SendAction::Type::UploadFile, -1);
|
||||||
}
|
}
|
||||||
Ui::repaintHistoryItem(item);
|
Ui::repaintHistoryItem(item);
|
||||||
}
|
}
|
||||||
|
@ -7051,7 +7033,7 @@ bool HistoryWidget::isItemVisible(HistoryItem *item) {
|
||||||
|
|
||||||
void HistoryWidget::ui_repaintHistoryItem(const HistoryItem *item) {
|
void HistoryWidget::ui_repaintHistoryItem(const HistoryItem *item) {
|
||||||
if (_peer && _list && (item->history() == _history || (_migrated && item->history() == _migrated))) {
|
if (_peer && _list && (item->history() == _history || (_migrated && item->history() == _migrated))) {
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
if (_lastScrolled + 100 <= ms) {
|
if (_lastScrolled + 100 <= ms) {
|
||||||
_list->repaintItem(item);
|
_list->repaintItem(item);
|
||||||
} else {
|
} else {
|
||||||
|
@ -7063,7 +7045,7 @@ void HistoryWidget::ui_repaintHistoryItem(const HistoryItem *item) {
|
||||||
void HistoryWidget::onUpdateHistoryItems() {
|
void HistoryWidget::onUpdateHistoryItems() {
|
||||||
if (!_list) return;
|
if (!_list) return;
|
||||||
|
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
if (_lastScrolled + 100 <= ms) {
|
if (_lastScrolled + 100 <= ms) {
|
||||||
_list->update();
|
_list->update();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -261,9 +261,9 @@ private:
|
||||||
bool _touchPrevPosValid = false;
|
bool _touchPrevPosValid = false;
|
||||||
bool _touchWaitingAcceleration = false;
|
bool _touchWaitingAcceleration = false;
|
||||||
QPoint _touchSpeed;
|
QPoint _touchSpeed;
|
||||||
uint64 _touchSpeedTime = 0;
|
TimeMs _touchSpeedTime = 0;
|
||||||
uint64 _touchAccelerationTime = 0;
|
TimeMs _touchAccelerationTime = 0;
|
||||||
uint64 _touchTime = 0;
|
TimeMs _touchTime = 0;
|
||||||
QTimer _touchScrollTimer;
|
QTimer _touchScrollTimer;
|
||||||
|
|
||||||
// context menu
|
// context menu
|
||||||
|
@ -385,7 +385,7 @@ public:
|
||||||
bool hasMarkup() const;
|
bool hasMarkup() const;
|
||||||
bool forceReply() const;
|
bool forceReply() const;
|
||||||
|
|
||||||
void step_selected(uint64 ms, bool timer);
|
void step_selected(TimeMs ms, bool timer);
|
||||||
void resizeToWidth(int newWidth, int maxOuterHeight) {
|
void resizeToWidth(int newWidth, int maxOuterHeight) {
|
||||||
_maxOuterHeight = maxOuterHeight;
|
_maxOuterHeight = maxOuterHeight;
|
||||||
return TWidget::resizeToWidth(newWidth);
|
return TWidget::resizeToWidth(newWidth);
|
||||||
|
@ -552,7 +552,7 @@ public:
|
||||||
|
|
||||||
void updateTopBarSelection();
|
void updateTopBarSelection();
|
||||||
|
|
||||||
bool paintTopBar(Painter &p, int decreaseWidth);
|
bool paintTopBar(Painter &p, int decreaseWidth, TimeMs ms);
|
||||||
QRect getMembersShowAreaGeometry() const;
|
QRect getMembersShowAreaGeometry() const;
|
||||||
void setMembersShowAreaActive(bool active);
|
void setMembersShowAreaActive(bool active);
|
||||||
void topBarClick();
|
void topBarClick();
|
||||||
|
@ -572,8 +572,8 @@ public:
|
||||||
|
|
||||||
QRect historyRect() const;
|
QRect historyRect() const;
|
||||||
|
|
||||||
void updateSendAction(History *history, SendActionType type, int32 progress = 0);
|
void updateSendAction(History *history, SendAction::Type type, int32 progress = 0);
|
||||||
void cancelSendAction(History *history, SendActionType type);
|
void cancelSendAction(History *history, SendAction::Type type);
|
||||||
|
|
||||||
void updateRecentStickers();
|
void updateRecentStickers();
|
||||||
void stickersInstalled(uint64 setId);
|
void stickersInstalled(uint64 setId);
|
||||||
|
@ -1085,7 +1085,7 @@ private:
|
||||||
int _addToScroll = 0;
|
int _addToScroll = 0;
|
||||||
|
|
||||||
int _lastScroll = 0;// gifs optimization
|
int _lastScroll = 0;// gifs optimization
|
||||||
uint64 _lastScrolled = 0;
|
TimeMs _lastScrolled = 0;
|
||||||
QTimer _updateHistoryItems;
|
QTimer _updateHistoryItems;
|
||||||
|
|
||||||
ChildWidget<Ui::HistoryDownButton> _historyToEnd;
|
ChildWidget<Ui::HistoryDownButton> _historyToEnd;
|
||||||
|
@ -1174,10 +1174,10 @@ private:
|
||||||
QTimer _animActiveTimer;
|
QTimer _animActiveTimer;
|
||||||
float64 _animActiveStart = 0;
|
float64 _animActiveStart = 0;
|
||||||
|
|
||||||
QMap<QPair<History*, SendActionType>, mtpRequestId> _sendActionRequests;
|
QMap<QPair<History*, SendAction::Type>, mtpRequestId> _sendActionRequests;
|
||||||
QTimer _sendActionStopTimer;
|
QTimer _sendActionStopTimer;
|
||||||
|
|
||||||
uint64 _saveDraftStart = 0;
|
TimeMs _saveDraftStart = 0;
|
||||||
bool _saveDraftText = false;
|
bool _saveDraftText = false;
|
||||||
QTimer _saveDraftTimer, _saveCloudDraftTimer;
|
QTimer _saveDraftTimer, _saveCloudDraftTimer;
|
||||||
|
|
||||||
|
|
|
@ -308,14 +308,14 @@ void Gif::ensureAnimation() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Gif::isRadialAnimation(uint64 ms) const {
|
bool Gif::isRadialAnimation(TimeMs ms) const {
|
||||||
if (!_animation || !_animation->radial.animating()) return false;
|
if (!_animation || !_animation->radial.animating()) return false;
|
||||||
|
|
||||||
_animation->radial.step(ms);
|
_animation->radial.step(ms);
|
||||||
return _animation && _animation->radial.animating();
|
return _animation && _animation->radial.animating();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gif::step_radial(uint64 ms, bool timer) {
|
void Gif::step_radial(TimeMs ms, bool timer) {
|
||||||
if (timer) {
|
if (timer) {
|
||||||
update();
|
update();
|
||||||
} else {
|
} else {
|
||||||
|
@ -811,7 +811,7 @@ void File::step_thumbOver(float64 ms, bool timer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void File::step_radial(uint64 ms, bool timer) {
|
void File::step_radial(TimeMs ms, bool timer) {
|
||||||
if (timer) {
|
if (timer) {
|
||||||
Ui::repaintInlineItem(this);
|
Ui::repaintInlineItem(this);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1319,14 +1319,14 @@ void Game::prepareThumb(int width, int height) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Game::isRadialAnimation(uint64 ms) const {
|
bool Game::isRadialAnimation(TimeMs ms) const {
|
||||||
if (!_radial || !_radial->animating()) return false;
|
if (!_radial || !_radial->animating()) return false;
|
||||||
|
|
||||||
_radial->step(ms);
|
_radial->step(ms);
|
||||||
return _radial && _radial->animating();
|
return _radial && _radial->animating();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::step_radial(uint64 ms, bool timer) {
|
void Game::step_radial(TimeMs ms, bool timer) {
|
||||||
if (timer) {
|
if (timer) {
|
||||||
update();
|
update();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -96,8 +96,8 @@ private:
|
||||||
void prepareThumb(int32 width, int32 height, const QSize &frame) const;
|
void prepareThumb(int32 width, int32 height, const QSize &frame) const;
|
||||||
|
|
||||||
void ensureAnimation() const;
|
void ensureAnimation() const;
|
||||||
bool isRadialAnimation(uint64 ms) const;
|
bool isRadialAnimation(TimeMs ms) const;
|
||||||
void step_radial(uint64 ms, bool timer);
|
void step_radial(TimeMs ms, bool timer);
|
||||||
|
|
||||||
void clipCallback(Media::Clip::Notification notification);
|
void clipCallback(Media::Clip::Notification notification);
|
||||||
|
|
||||||
|
@ -243,19 +243,19 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void step_thumbOver(float64 ms, bool timer);
|
void step_thumbOver(float64 ms, bool timer);
|
||||||
void step_radial(uint64 ms, bool timer);
|
void step_radial(TimeMs ms, bool timer);
|
||||||
|
|
||||||
void ensureAnimation() const;
|
void ensureAnimation() const;
|
||||||
void checkAnimationFinished();
|
void checkAnimationFinished();
|
||||||
bool updateStatusText() const;
|
bool updateStatusText() const;
|
||||||
|
|
||||||
bool isRadialAnimation(uint64 ms) const {
|
bool isRadialAnimation(TimeMs ms) const {
|
||||||
if (!_animation || !_animation->radial.animating()) return false;
|
if (!_animation || !_animation->radial.animating()) return false;
|
||||||
|
|
||||||
_animation->radial.step(ms);
|
_animation->radial.step(ms);
|
||||||
return _animation && _animation->radial.animating();
|
return _animation && _animation->radial.animating();
|
||||||
}
|
}
|
||||||
bool isThumbAnimation(uint64 ms) const {
|
bool isThumbAnimation(TimeMs ms) const {
|
||||||
if (!_animation || !_animation->_a_thumbOver.animating()) return false;
|
if (!_animation || !_animation->_a_thumbOver.animating()) return false;
|
||||||
|
|
||||||
_animation->_a_thumbOver.step(ms);
|
_animation->_a_thumbOver.step(ms);
|
||||||
|
@ -348,8 +348,8 @@ private:
|
||||||
|
|
||||||
void prepareThumb(int32 width, int32 height) const;
|
void prepareThumb(int32 width, int32 height) const;
|
||||||
|
|
||||||
bool isRadialAnimation(uint64 ms) const;
|
bool isRadialAnimation(TimeMs ms) const;
|
||||||
void step_radial(uint64 ms, bool timer);
|
void step_radial(TimeMs ms, bool timer);
|
||||||
|
|
||||||
void clipCallback(Media::Clip::Notification notification);
|
void clipCallback(Media::Clip::Notification notification);
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace Layout {
|
||||||
|
|
||||||
class PaintContext : public PaintContextBase {
|
class PaintContext : public PaintContextBase {
|
||||||
public:
|
public:
|
||||||
PaintContext(uint64 ms, bool selecting, bool paused, bool lastRow)
|
PaintContext(TimeMs ms, bool selecting, bool paused, bool lastRow)
|
||||||
: PaintContextBase(ms, selecting)
|
: PaintContextBase(ms, selecting)
|
||||||
, paused(paused)
|
, paused(paused)
|
||||||
, lastRow(lastRow) {
|
, lastRow(lastRow) {
|
||||||
|
|
|
@ -92,9 +92,9 @@ bool documentIsValidMediaFile(const QString &filepath);
|
||||||
|
|
||||||
class PaintContextBase {
|
class PaintContextBase {
|
||||||
public:
|
public:
|
||||||
PaintContextBase(uint64 ms, bool selecting) : ms(ms), selecting(selecting) {
|
PaintContextBase(TimeMs ms, bool selecting) : ms(ms), selecting(selecting) {
|
||||||
}
|
}
|
||||||
uint64 ms;
|
TimeMs ms;
|
||||||
bool selecting;
|
bool selecting;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1748,7 +1748,7 @@ void _readMtpData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadMapState _readMap(const QByteArray &pass) {
|
ReadMapState _readMap(const QByteArray &pass) {
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
QByteArray dataNameUtf8 = (cDataFile() + (cTestMode() ? qsl(":/test/") : QString())).toUtf8();
|
QByteArray dataNameUtf8 = (cDataFile() + (cTestMode() ? qsl(":/test/") : QString())).toUtf8();
|
||||||
FileKey dataNameHash[2];
|
FileKey dataNameHash[2];
|
||||||
hashMd5(dataNameUtf8.constData(), dataNameUtf8.size(), dataNameHash);
|
hashMd5(dataNameUtf8.constData(), dataNameUtf8.size(), dataNameHash);
|
||||||
|
|
|
@ -1292,7 +1292,7 @@ void MainWidget::unreadCountChanged(History *history) {
|
||||||
_history->unreadCountChanged(history);
|
_history->unreadCountChanged(history);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 MainWidget::animActiveTimeStart(const HistoryItem *msg) const {
|
TimeMs MainWidget::animActiveTimeStart(const HistoryItem *msg) const {
|
||||||
return _history->animActiveTimeStart(msg);
|
return _history->animActiveTimeStart(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1449,7 +1449,7 @@ void MainWidget::loadMediaBack(PeerData *peer, MediaOverviewType type, bool many
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::checkLastUpdate(bool afterSleep) {
|
void MainWidget::checkLastUpdate(bool afterSleep) {
|
||||||
uint64 n = getms(true);
|
auto n = getms(true);
|
||||||
if (_lastUpdateTime && n > _lastUpdateTime + (afterSleep ? NoUpdatesAfterSleepTimeout : NoUpdatesTimeout)) {
|
if (_lastUpdateTime && n > _lastUpdateTime + (afterSleep ? NoUpdatesAfterSleepTimeout : NoUpdatesTimeout)) {
|
||||||
_lastUpdateTime = n;
|
_lastUpdateTime = n;
|
||||||
MTP::ping();
|
MTP::ping();
|
||||||
|
@ -2969,11 +2969,11 @@ bool MainWidget::needBackButton() {
|
||||||
return _overview || _wideSection || _history->peer();
|
return _overview || _wideSection || _history->peer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWidget::paintTopBar(Painter &p, int decreaseWidth) {
|
bool MainWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
|
||||||
if (_overview) {
|
if (_overview) {
|
||||||
return _overview->paintTopBar(p, decreaseWidth);
|
return _overview->paintTopBar(p, decreaseWidth);
|
||||||
} else if (!_wideSection) {
|
} else if (!_wideSection) {
|
||||||
return _history->paintTopBar(p, decreaseWidth);
|
return _history->paintTopBar(p, decreaseWidth, ms);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3325,7 +3325,7 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWidget::getDifferenceTimeChanged(ChannelData *channel, int32 ms, ChannelGetDifferenceTime &channelCurTime, uint64 &curTime) {
|
bool MainWidget::getDifferenceTimeChanged(ChannelData *channel, int32 ms, ChannelGetDifferenceTime &channelCurTime, TimeMs &curTime) {
|
||||||
if (channel) {
|
if (channel) {
|
||||||
if (ms <= 0) {
|
if (ms <= 0) {
|
||||||
ChannelGetDifferenceTime::iterator i = channelCurTime.find(channel);
|
ChannelGetDifferenceTime::iterator i = channelCurTime.find(channel);
|
||||||
|
@ -3335,7 +3335,7 @@ bool MainWidget::getDifferenceTimeChanged(ChannelData *channel, int32 ms, Channe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint64 when = getms(true) + ms;
|
auto when = getms(true) + ms;
|
||||||
ChannelGetDifferenceTime::iterator i = channelCurTime.find(channel);
|
ChannelGetDifferenceTime::iterator i = channelCurTime.find(channel);
|
||||||
if (i != channelCurTime.cend()) {
|
if (i != channelCurTime.cend()) {
|
||||||
if (i.value() > when) {
|
if (i.value() > when) {
|
||||||
|
@ -3355,7 +3355,7 @@ bool MainWidget::getDifferenceTimeChanged(ChannelData *channel, int32 ms, Channe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint64 when = getms(true) + ms;
|
auto when = getms(true) + ms;
|
||||||
if (!curTime || curTime > when) {
|
if (!curTime || curTime > when) {
|
||||||
curTime = when;
|
curTime = when;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3431,7 +3431,7 @@ bool MainWidget::failDifference(const RPCError &error) {
|
||||||
void MainWidget::onGetDifferenceTimeByPts() {
|
void MainWidget::onGetDifferenceTimeByPts() {
|
||||||
if (!MTP::authedId()) return;
|
if (!MTP::authedId()) return;
|
||||||
|
|
||||||
uint64 now = getms(true), wait = 0;
|
auto now = getms(true), wait = 0LL;
|
||||||
if (_getDifferenceTimeByPts) {
|
if (_getDifferenceTimeByPts) {
|
||||||
if (_getDifferenceTimeByPts > now) {
|
if (_getDifferenceTimeByPts > now) {
|
||||||
wait = _getDifferenceTimeByPts - now;
|
wait = _getDifferenceTimeByPts - now;
|
||||||
|
@ -3458,7 +3458,7 @@ void MainWidget::onGetDifferenceTimeByPts() {
|
||||||
void MainWidget::onGetDifferenceTimeAfterFail() {
|
void MainWidget::onGetDifferenceTimeAfterFail() {
|
||||||
if (!MTP::authedId()) return;
|
if (!MTP::authedId()) return;
|
||||||
|
|
||||||
uint64 now = getms(true), wait = 0;
|
auto now = getms(true), wait = 0LL;
|
||||||
if (_getDifferenceTimeAfterFail) {
|
if (_getDifferenceTimeAfterFail) {
|
||||||
if (_getDifferenceTimeAfterFail > now) {
|
if (_getDifferenceTimeAfterFail > now) {
|
||||||
wait = _getDifferenceTimeAfterFail - now;
|
wait = _getDifferenceTimeAfterFail - now;
|
||||||
|
@ -3468,7 +3468,7 @@ void MainWidget::onGetDifferenceTimeAfterFail() {
|
||||||
getDifference();
|
getDifference();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ChannelGetDifferenceTime::iterator i = _channelGetDifferenceTimeAfterFail.begin(); i != _channelGetDifferenceTimeAfterFail.cend();) {
|
for (auto i = _channelGetDifferenceTimeAfterFail.begin(); i != _channelGetDifferenceTimeAfterFail.cend();) {
|
||||||
if (i.value() > now) {
|
if (i.value() > now) {
|
||||||
wait = wait ? qMin(wait, i.value() - now) : (i.value() - now);
|
wait = wait ? qMin(wait, i.value() - now) : (i.value() - now);
|
||||||
++i;
|
++i;
|
||||||
|
@ -4054,7 +4054,7 @@ bool MainWidget::lastWasOnline() const {
|
||||||
return _lastWasOnline;
|
return _lastWasOnline;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 MainWidget::lastSetOnline() const {
|
TimeMs MainWidget::lastSetOnline() const {
|
||||||
return _lastSetOnline;
|
return _lastSetOnline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4081,8 +4081,8 @@ void MainWidget::updateOnline(bool gotOtherOffline) {
|
||||||
bool isOnline = App::wnd()->isActive();
|
bool isOnline = App::wnd()->isActive();
|
||||||
int updateIn = Global::OnlineUpdatePeriod();
|
int updateIn = Global::OnlineUpdatePeriod();
|
||||||
if (isOnline) {
|
if (isOnline) {
|
||||||
uint64 idle = psIdleTime();
|
auto idle = psIdleTime();
|
||||||
if (idle >= uint64(Global::OfflineIdleTimeout())) {
|
if (idle >= Global::OfflineIdleTimeout()) {
|
||||||
isOnline = false;
|
isOnline = false;
|
||||||
if (!_isIdle) {
|
if (!_isIdle) {
|
||||||
_isIdle = true;
|
_isIdle = true;
|
||||||
|
@ -4092,7 +4092,7 @@ void MainWidget::updateOnline(bool gotOtherOffline) {
|
||||||
updateIn = qMin(updateIn, int(Global::OfflineIdleTimeout() - idle));
|
updateIn = qMin(updateIn, int(Global::OfflineIdleTimeout() - idle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint64 ms = getms(true);
|
auto ms = getms(true);
|
||||||
if (isOnline != _lastWasOnline || (isOnline && _lastSetOnline + Global::OnlineUpdatePeriod() <= ms) || (isOnline && gotOtherOffline)) {
|
if (isOnline != _lastWasOnline || (isOnline && _lastSetOnline + Global::OnlineUpdatePeriod() <= ms) || (isOnline && gotOtherOffline)) {
|
||||||
if (_onlineRequest) {
|
if (_onlineRequest) {
|
||||||
MTP::cancel(_onlineRequest);
|
MTP::cancel(_onlineRequest);
|
||||||
|
@ -4158,7 +4158,7 @@ void MainWidget::writeDrafts(History *history) {
|
||||||
|
|
||||||
void MainWidget::checkIdleFinish() {
|
void MainWidget::checkIdleFinish() {
|
||||||
if (this != App::main()) return;
|
if (this != App::main()) return;
|
||||||
if (psIdleTime() < uint64(Global::OfflineIdleTimeout())) {
|
if (psIdleTime() < Global::OfflineIdleTimeout()) {
|
||||||
_idleFinishTimer.stop();
|
_idleFinishTimer.stop();
|
||||||
_isIdle = false;
|
_isIdle = false;
|
||||||
updateOnline();
|
updateOnline();
|
||||||
|
@ -4481,7 +4481,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
if (App::wnd()) App::wnd()->changingMsgId(msgRow, d.vid.v);
|
if (App::wnd()) App::wnd()->changingMsgId(msgRow, d.vid.v);
|
||||||
msgRow->setId(d.vid.v);
|
msgRow->setId(d.vid.v);
|
||||||
if (msgRow->history()->peer->isSelf()) {
|
if (msgRow->history()->peer->isSelf()) {
|
||||||
msgRow->history()->unregTyping(App::self());
|
msgRow->history()->unregSendAction(App::self());
|
||||||
}
|
}
|
||||||
App::historyRegItem(msgRow);
|
App::historyRegItem(msgRow);
|
||||||
Ui::repaintHistoryItem(msgRow);
|
Ui::repaintHistoryItem(msgRow);
|
||||||
|
|
|
@ -144,7 +144,7 @@ public:
|
||||||
bool needBackButton();
|
bool needBackButton();
|
||||||
|
|
||||||
// Temporary methods, while top bar was not done inside HistoryWidget / OverviewWidget.
|
// Temporary methods, while top bar was not done inside HistoryWidget / OverviewWidget.
|
||||||
bool paintTopBar(Painter &, int decreaseWidth);
|
bool paintTopBar(Painter &, int decreaseWidth, TimeMs ms);
|
||||||
QRect getMembersShowAreaGeometry() const;
|
QRect getMembersShowAreaGeometry() const;
|
||||||
void setMembersShowAreaActive(bool active);
|
void setMembersShowAreaActive(bool active);
|
||||||
Window::TopBarWidget *topBar();
|
Window::TopBarWidget *topBar();
|
||||||
|
@ -221,7 +221,7 @@ public:
|
||||||
bool isActive() const;
|
bool isActive() const;
|
||||||
bool doWeReadServerHistory() const;
|
bool doWeReadServerHistory() const;
|
||||||
bool lastWasOnline() const;
|
bool lastWasOnline() const;
|
||||||
uint64 lastSetOnline() const;
|
TimeMs lastSetOnline() const;
|
||||||
|
|
||||||
void saveDraftToCloud();
|
void saveDraftToCloud();
|
||||||
void applyCloudDraft(History *history);
|
void applyCloudDraft(History *history);
|
||||||
|
@ -293,7 +293,7 @@ public:
|
||||||
void readServerHistory(History *history, ReadServerHistoryChecks checks = ReadServerHistoryChecks::OnlyIfUnread);
|
void readServerHistory(History *history, ReadServerHistoryChecks checks = ReadServerHistoryChecks::OnlyIfUnread);
|
||||||
void unreadCountChanged(History *history);
|
void unreadCountChanged(History *history);
|
||||||
|
|
||||||
uint64 animActiveTimeStart(const HistoryItem *msg) const;
|
TimeMs animActiveTimeStart(const HistoryItem *msg) const;
|
||||||
void stopAnimActive();
|
void stopAnimActive();
|
||||||
|
|
||||||
void sendBotCommand(PeerData *peer, UserData *bot, const QString &cmd, MsgId replyTo);
|
void sendBotCommand(PeerData *peer, UserData *bot, const QString &cmd, MsgId replyTo);
|
||||||
|
@ -633,12 +633,12 @@ private:
|
||||||
return _ptsWaiter.requesting();
|
return _ptsWaiter.requesting();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef QMap<ChannelData*, uint64> ChannelGetDifferenceTime;
|
typedef QMap<ChannelData*, TimeMs> ChannelGetDifferenceTime;
|
||||||
ChannelGetDifferenceTime _channelGetDifferenceTimeByPts, _channelGetDifferenceTimeAfterFail;
|
ChannelGetDifferenceTime _channelGetDifferenceTimeByPts, _channelGetDifferenceTimeAfterFail;
|
||||||
uint64 _getDifferenceTimeByPts = 0;
|
TimeMs _getDifferenceTimeByPts = 0;
|
||||||
uint64 _getDifferenceTimeAfterFail = 0;
|
TimeMs _getDifferenceTimeAfterFail = 0;
|
||||||
|
|
||||||
bool getDifferenceTimeChanged(ChannelData *channel, int32 ms, ChannelGetDifferenceTime &channelCurTime, uint64 &curTime);
|
bool getDifferenceTimeChanged(ChannelData *channel, int32 ms, ChannelGetDifferenceTime &channelCurTime, TimeMs &curTime);
|
||||||
|
|
||||||
SingleTimer _byPtsTimer;
|
SingleTimer _byPtsTimer;
|
||||||
|
|
||||||
|
@ -650,7 +650,7 @@ private:
|
||||||
mtpRequestId _onlineRequest = 0;
|
mtpRequestId _onlineRequest = 0;
|
||||||
SingleTimer _onlineTimer, _onlineUpdater, _idleFinishTimer;
|
SingleTimer _onlineTimer, _onlineUpdater, _idleFinishTimer;
|
||||||
bool _lastWasOnline = false;
|
bool _lastWasOnline = false;
|
||||||
uint64 _lastSetOnline = 0;
|
TimeMs _lastSetOnline = 0;
|
||||||
bool _isIdle = false;
|
bool _isIdle = false;
|
||||||
|
|
||||||
QSet<PeerData*> updateNotifySettingPeers;
|
QSet<PeerData*> updateNotifySettingPeers;
|
||||||
|
@ -669,7 +669,7 @@ private:
|
||||||
ChannelFailDifferenceTimeout _channelFailDifferenceTimeout; // growing timeout for getChannelDifference calls, if it fails
|
ChannelFailDifferenceTimeout _channelFailDifferenceTimeout; // growing timeout for getChannelDifference calls, if it fails
|
||||||
SingleTimer _failDifferenceTimer;
|
SingleTimer _failDifferenceTimer;
|
||||||
|
|
||||||
uint64 _lastUpdateTime = 0;
|
TimeMs _lastUpdateTime = 0;
|
||||||
bool _handlingChannelDifference = false;
|
bool _handlingChannelDifference = false;
|
||||||
|
|
||||||
QPixmap _cachedBackground;
|
QPixmap _cachedBackground;
|
||||||
|
|
|
@ -285,7 +285,7 @@ void MainWindow::checkAutoLock() {
|
||||||
if (!Global::LocalPasscode() || App::passcoded()) return;
|
if (!Global::LocalPasscode() || App::passcoded()) return;
|
||||||
|
|
||||||
App::app()->checkLocalTime();
|
App::app()->checkLocalTime();
|
||||||
uint64 ms = getms(true), idle = psIdleTime(), should = Global::AutoLock() * 1000ULL;
|
auto ms = getms(true), idle = psIdleTime(), should = Global::AutoLock() * 1000LL;
|
||||||
if (idle >= should || (_shouldLockAt > 0 && ms > _shouldLockAt + 3000ULL)) {
|
if (idle >= should || (_shouldLockAt > 0 && ms > _shouldLockAt + 3000ULL)) {
|
||||||
setupPasscode();
|
setupPasscode();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1043,16 +1043,16 @@ void MainWindow::notifySchedule(History *history, HistoryItem *item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int delay = item->Has<HistoryMessageForwarded>() ? 500 : 100, t = unixtime();
|
int delay = item->Has<HistoryMessageForwarded>() ? 500 : 100, t = unixtime();
|
||||||
uint64 ms = getms(true);
|
auto ms = getms(true);
|
||||||
bool isOnline = _main->lastWasOnline(), otherNotOld = ((cOtherOnline() * uint64(1000)) + Global::OnlineCloudTimeout() > t * uint64(1000));
|
bool isOnline = _main->lastWasOnline(), otherNotOld = ((cOtherOnline() * 1000LL) + Global::OnlineCloudTimeout() > t * 1000LL);
|
||||||
bool otherLaterThanMe = (cOtherOnline() * uint64(1000) + (ms - _main->lastSetOnline()) > t * uint64(1000));
|
bool otherLaterThanMe = (cOtherOnline() * 1000LL + (ms - _main->lastSetOnline()) > t * 1000LL);
|
||||||
if (!isOnline && otherNotOld && otherLaterThanMe) {
|
if (!isOnline && otherNotOld && otherLaterThanMe) {
|
||||||
delay = Global::NotifyCloudDelay();
|
delay = Global::NotifyCloudDelay();
|
||||||
} else if (cOtherOnline() >= t) {
|
} else if (cOtherOnline() >= t) {
|
||||||
delay = Global::NotifyDefaultDelay();
|
delay = Global::NotifyDefaultDelay();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 when = ms + delay;
|
auto when = ms + delay;
|
||||||
_notifyWhenAlerts[history].insert(when, notifyByFrom);
|
_notifyWhenAlerts[history].insert(when, notifyByFrom);
|
||||||
if (Global::DesktopNotify() && !Platform::Notifications::skipToast()) {
|
if (Global::DesktopNotify() && !Platform::Notifications::skipToast()) {
|
||||||
NotifyWhenMaps::iterator i = _notifyWhenMaps.find(history);
|
NotifyWhenMaps::iterator i = _notifyWhenMaps.find(history);
|
||||||
|
@ -1155,7 +1155,7 @@ void MainWindow::notifySettingGot() {
|
||||||
void MainWindow::notifyShowNext() {
|
void MainWindow::notifyShowNext() {
|
||||||
if (App::quitting()) return;
|
if (App::quitting()) return;
|
||||||
|
|
||||||
uint64 ms = getms(true), nextAlert = 0;
|
auto ms = getms(true), nextAlert = 0LL;
|
||||||
bool alert = false;
|
bool alert = false;
|
||||||
int32 now = unixtime();
|
int32 now = unixtime();
|
||||||
for (NotifyWhenAlerts::iterator i = _notifyWhenAlerts.begin(); i != _notifyWhenAlerts.end();) {
|
for (NotifyWhenAlerts::iterator i = _notifyWhenAlerts.begin(); i != _notifyWhenAlerts.end();) {
|
||||||
|
@ -1192,7 +1192,7 @@ void MainWindow::notifyShowNext() {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
uint64 next = 0;
|
auto next = 0LL;
|
||||||
HistoryItem *notifyItem = 0;
|
HistoryItem *notifyItem = 0;
|
||||||
History *notifyHistory = 0;
|
History *notifyHistory = 0;
|
||||||
for (NotifyWaiters::iterator i = _notifyWaiters.begin(); i != _notifyWaiters.end();) {
|
for (NotifyWaiters::iterator i = _notifyWaiters.begin(); i != _notifyWaiters.end();) {
|
||||||
|
@ -1219,7 +1219,7 @@ void MainWindow::notifyShowNext() {
|
||||||
i = _notifyWaiters.erase(i);
|
i = _notifyWaiters.erase(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint64 when = i.value().when;
|
auto when = i.value().when;
|
||||||
if (!notifyItem || next > when) {
|
if (!notifyItem || next > when) {
|
||||||
next = when;
|
next = when;
|
||||||
notifyItem = history->currentNotification();
|
notifyItem = history->currentNotification();
|
||||||
|
@ -1239,7 +1239,7 @@ void MainWindow::notifyShowNext() {
|
||||||
HistoryItem *fwd = notifyItem->Has<HistoryMessageForwarded>() ? notifyItem : nullptr; // forwarded notify grouping
|
HistoryItem *fwd = notifyItem->Has<HistoryMessageForwarded>() ? notifyItem : nullptr; // forwarded notify grouping
|
||||||
int32 fwdCount = 1;
|
int32 fwdCount = 1;
|
||||||
|
|
||||||
uint64 ms = getms(true);
|
auto ms = getms(true);
|
||||||
History *history = notifyItem->history();
|
History *history = notifyItem->history();
|
||||||
NotifyWhenMaps::iterator j = _notifyWhenMaps.find(history);
|
NotifyWhenMaps::iterator j = _notifyWhenMaps.find(history);
|
||||||
if (j == _notifyWhenMaps.cend()) {
|
if (j == _notifyWhenMaps.cend()) {
|
||||||
|
|
|
@ -261,19 +261,19 @@ private:
|
||||||
QTimer _inactiveTimer;
|
QTimer _inactiveTimer;
|
||||||
|
|
||||||
SingleTimer _autoLockTimer;
|
SingleTimer _autoLockTimer;
|
||||||
uint64 _shouldLockAt = 0;
|
TimeMs _shouldLockAt = 0;
|
||||||
|
|
||||||
using NotifyWhenMap = QMap<MsgId, uint64>;
|
using NotifyWhenMap = QMap<MsgId, TimeMs>;
|
||||||
using NotifyWhenMaps = QMap<History*, NotifyWhenMap>;
|
using NotifyWhenMaps = QMap<History*, NotifyWhenMap>;
|
||||||
NotifyWhenMaps _notifyWhenMaps;
|
NotifyWhenMaps _notifyWhenMaps;
|
||||||
struct NotifyWaiter {
|
struct NotifyWaiter {
|
||||||
NotifyWaiter(MsgId msg, uint64 when, PeerData *notifyByFrom)
|
NotifyWaiter(MsgId msg, TimeMs when, PeerData *notifyByFrom)
|
||||||
: msg(msg)
|
: msg(msg)
|
||||||
, when(when)
|
, when(when)
|
||||||
, notifyByFrom(notifyByFrom) {
|
, notifyByFrom(notifyByFrom) {
|
||||||
}
|
}
|
||||||
MsgId msg;
|
MsgId msg;
|
||||||
uint64 when;
|
TimeMs when;
|
||||||
PeerData *notifyByFrom;
|
PeerData *notifyByFrom;
|
||||||
};
|
};
|
||||||
using NotifyWaiters = QMap<History*, NotifyWaiter>;
|
using NotifyWaiters = QMap<History*, NotifyWaiter>;
|
||||||
|
@ -281,7 +281,7 @@ private:
|
||||||
NotifyWaiters _notifySettingWaiters;
|
NotifyWaiters _notifySettingWaiters;
|
||||||
SingleTimer _notifyWaitTimer;
|
SingleTimer _notifyWaitTimer;
|
||||||
|
|
||||||
using NotifyWhenAlert = QMap<uint64, PeerData*>;
|
using NotifyWhenAlert = QMap<TimeMs, PeerData*>;
|
||||||
using NotifyWhenAlerts = QMap<History*, NotifyWhenAlert>;
|
using NotifyWhenAlerts = QMap<History*, NotifyWhenAlert>;
|
||||||
NotifyWhenAlerts _notifyWhenAlerts;
|
NotifyWhenAlerts _notifyWhenAlerts;
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace {
|
||||||
ALuint notifySource = 0;
|
ALuint notifySource = 0;
|
||||||
ALuint notifyBuffer = 0;
|
ALuint notifyBuffer = 0;
|
||||||
|
|
||||||
uint64 notifyLengthMs = 0;
|
TimeMs notifyLengthMs = 0;
|
||||||
|
|
||||||
QMutex playerMutex;
|
QMutex playerMutex;
|
||||||
AudioPlayer *player = 0;
|
AudioPlayer *player = 0;
|
||||||
|
@ -669,12 +669,12 @@ void AudioPlayer::feedFromVideo(VideoSoundPart &&part) {
|
||||||
_loader->feedFromVideo(std_::move(part));
|
_loader->feedFromVideo(std_::move(part));
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 AudioPlayer::getVideoCorrectedTime(uint64 playId, int64 frameMs, uint64 systemMs) {
|
TimeMs AudioPlayer::getVideoCorrectedTime(uint64 playId, TimeMs frameMs, TimeMs systemMs) {
|
||||||
int64 result = frameMs;
|
auto result = frameMs;
|
||||||
|
|
||||||
QMutexLocker videoLock(&_lastVideoMutex);
|
QMutexLocker videoLock(&_lastVideoMutex);
|
||||||
if (_lastVideoPlayId == playId && _lastVideoPlaybackWhen > 0) {
|
if (_lastVideoPlayId == playId && _lastVideoPlaybackWhen > 0) {
|
||||||
result = static_cast<int64>(_lastVideoPlaybackCorrectedMs);
|
result = static_cast<TimeMs>(_lastVideoPlaybackCorrectedMs);
|
||||||
if (systemMs > _lastVideoPlaybackWhen) {
|
if (systemMs > _lastVideoPlaybackWhen) {
|
||||||
result += (systemMs - _lastVideoPlaybackWhen);
|
result += (systemMs - _lastVideoPlaybackWhen);
|
||||||
}
|
}
|
||||||
|
@ -985,7 +985,7 @@ void AudioPlayerFader::onTimer() {
|
||||||
|
|
||||||
bool suppressAudioChanged = false, suppressSongChanged = false;
|
bool suppressAudioChanged = false, suppressSongChanged = false;
|
||||||
if (_suppressAll || _suppressSongAnim) {
|
if (_suppressAll || _suppressSongAnim) {
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
float64 wasSong = suppressSongGain;
|
float64 wasSong = suppressSongGain;
|
||||||
if (_suppressAll) {
|
if (_suppressAll) {
|
||||||
float64 wasAudio = suppressAllGain;
|
float64 wasAudio = suppressAllGain;
|
||||||
|
|
|
@ -51,7 +51,7 @@ struct VideoSoundPart;
|
||||||
struct AudioPlaybackState {
|
struct AudioPlaybackState {
|
||||||
AudioPlayerState state = AudioPlayerStopped;
|
AudioPlayerState state = AudioPlayerStopped;
|
||||||
int64 position = 0;
|
int64 position = 0;
|
||||||
int64 duration = 0;
|
TimeMs duration = 0;
|
||||||
int32 frequency = 0;
|
int32 frequency = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ public:
|
||||||
// Video player audio stream interface.
|
// Video player audio stream interface.
|
||||||
void initFromVideo(uint64 videoPlayId, std_::unique_ptr<VideoSoundData> &&data, int64 position);
|
void initFromVideo(uint64 videoPlayId, std_::unique_ptr<VideoSoundData> &&data, int64 position);
|
||||||
void feedFromVideo(VideoSoundPart &&part);
|
void feedFromVideo(VideoSoundPart &&part);
|
||||||
int64 getVideoCorrectedTime(uint64 playId, int64 frameMs, uint64 systemMs);
|
int64 getVideoCorrectedTime(uint64 playId, TimeMs frameMs, TimeMs systemMs);
|
||||||
AudioPlaybackState currentVideoState(uint64 videoPlayId);
|
AudioPlaybackState currentVideoState(uint64 videoPlayId);
|
||||||
void stopFromVideo(uint64 videoPlayId);
|
void stopFromVideo(uint64 videoPlayId);
|
||||||
void pauseFromVideo(uint64 videoPlayId);
|
void pauseFromVideo(uint64 videoPlayId);
|
||||||
|
@ -155,8 +155,8 @@ private:
|
||||||
|
|
||||||
AudioMsg _videoData;
|
AudioMsg _videoData;
|
||||||
uint64 _lastVideoPlayId = 0;
|
uint64 _lastVideoPlayId = 0;
|
||||||
uint64 _lastVideoPlaybackWhen = 0;
|
TimeMs _lastVideoPlaybackWhen = 0;
|
||||||
uint64 _lastVideoPlaybackCorrectedMs = 0;
|
TimeMs _lastVideoPlaybackCorrectedMs = 0;
|
||||||
QMutex _lastVideoMutex;
|
QMutex _lastVideoMutex;
|
||||||
|
|
||||||
QMutex _mutex;
|
QMutex _mutex;
|
||||||
|
@ -258,8 +258,8 @@ private:
|
||||||
bool _suppressSongAnim = false;
|
bool _suppressSongAnim = false;
|
||||||
bool _songVolumeChanged, _videoVolumeChanged;
|
bool _songVolumeChanged, _videoVolumeChanged;
|
||||||
anim::fvalue _suppressAllGain, _suppressSongGain;
|
anim::fvalue _suppressAllGain, _suppressSongGain;
|
||||||
uint64 _suppressAllStart = 0;
|
TimeMs _suppressAllStart = 0;
|
||||||
uint64 _suppressSongStart = 0;
|
TimeMs _suppressSongStart = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
|
|
||||||
bool open(qint64 &position) override;
|
bool open(qint64 &position) override;
|
||||||
|
|
||||||
int64 duration() override {
|
TimeMs duration() override {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int32 freq = AudioVoiceMsgFrequency;
|
int32 freq = AudioVoiceMsgFrequency;
|
||||||
int64 len = 0;
|
TimeMs len = 0;
|
||||||
|
|
||||||
uchar *ioBuffer = nullptr;
|
uchar *ioBuffer = nullptr;
|
||||||
AVIOContext *ioContext = nullptr;
|
AVIOContext *ioContext = nullptr;
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
virtual bool check(const FileLocation &file, const QByteArray &data);
|
virtual bool check(const FileLocation &file, const QByteArray &data);
|
||||||
|
|
||||||
virtual bool open(qint64 &position) = 0;
|
virtual bool open(qint64 &position) = 0;
|
||||||
virtual int64 duration() = 0;
|
virtual TimeMs duration() = 0;
|
||||||
virtual int32 frequency() = 0;
|
virtual int32 frequency() = 0;
|
||||||
virtual int32 format() = 0;
|
virtual int32 format() = 0;
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ extern "C" {
|
||||||
struct VideoSoundData {
|
struct VideoSoundData {
|
||||||
AVCodecContext *context = nullptr;
|
AVCodecContext *context = nullptr;
|
||||||
int32 frequency = AudioVoiceMsgFrequency;
|
int32 frequency = AudioVoiceMsgFrequency;
|
||||||
int64 length = 0;
|
TimeMs length = 0;
|
||||||
~VideoSoundData();
|
~VideoSoundData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ public:
|
||||||
return _format;
|
return _format;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 duration() override {
|
TimeMs duration() override {
|
||||||
return _parentData->length;
|
return _parentData->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readNextFrame() {
|
||||||
void FFMpegReaderImplementation::processReadFrame() {
|
void FFMpegReaderImplementation::processReadFrame() {
|
||||||
int64 duration = av_frame_get_pkt_duration(_frame);
|
int64 duration = av_frame_get_pkt_duration(_frame);
|
||||||
int64 framePts = (_frame->pkt_pts == AV_NOPTS_VALUE) ? _frame->pkt_dts : _frame->pkt_pts;
|
int64 framePts = (_frame->pkt_pts == AV_NOPTS_VALUE) ? _frame->pkt_dts : _frame->pkt_pts;
|
||||||
int64 frameMs = (framePts * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
TimeMs frameMs = (framePts * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
||||||
_currentFrameDelay = _nextFrameDelay;
|
_currentFrameDelay = _nextFrameDelay;
|
||||||
if (_frameMs + _currentFrameDelay < frameMs) {
|
if (_frameMs + _currentFrameDelay < frameMs) {
|
||||||
_currentFrameDelay = int32(frameMs - _frameMs);
|
_currentFrameDelay = int32(frameMs - _frameMs);
|
||||||
|
@ -146,7 +146,7 @@ void FFMpegReaderImplementation::processReadFrame() {
|
||||||
_frameTime += _currentFrameDelay;
|
_frameTime += _currentFrameDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReaderImplementation::ReadResult FFMpegReaderImplementation::readFramesTill(int64 frameMs, uint64 systemMs) {
|
ReaderImplementation::ReadResult FFMpegReaderImplementation::readFramesTill(TimeMs frameMs, TimeMs systemMs) {
|
||||||
if (_audioStreamId < 0) { // just keep up
|
if (_audioStreamId < 0) { // just keep up
|
||||||
if (_frameRead && _frameTime > frameMs) {
|
if (_frameRead && _frameTime > frameMs) {
|
||||||
return ReadResult::Success;
|
return ReadResult::Success;
|
||||||
|
@ -182,15 +182,15 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readFramesTill(int6
|
||||||
return ReadResult::Success;
|
return ReadResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 FFMpegReaderImplementation::frameRealTime() const {
|
TimeMs FFMpegReaderImplementation::frameRealTime() const {
|
||||||
return _frameMs;
|
return _frameMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 FFMpegReaderImplementation::framePresentationTime() const {
|
TimeMs FFMpegReaderImplementation::framePresentationTime() const {
|
||||||
return static_cast<uint64>(qMax(_frameTime + _frameTimeCorrection, 0LL));
|
return qMax(_frameTime + _frameTimeCorrection, 0LL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 FFMpegReaderImplementation::durationMs() const {
|
TimeMs FFMpegReaderImplementation::durationMs() const {
|
||||||
if (_fmtContext->streams[_streamId]->duration == AV_NOPTS_VALUE) return 0;
|
if (_fmtContext->streams[_streamId]->duration == AV_NOPTS_VALUE) return 0;
|
||||||
return (_fmtContext->streams[_streamId]->duration * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
return (_fmtContext->streams[_streamId]->duration * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ FFMpegReaderImplementation::Rotation FFMpegReaderImplementation::rotationFromDeg
|
||||||
return Rotation::None;
|
return Rotation::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FFMpegReaderImplementation::start(Mode mode, int64 &positionMs) {
|
bool FFMpegReaderImplementation::start(Mode mode, TimeMs &positionMs) {
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
|
|
||||||
initDevice();
|
initDevice();
|
||||||
|
@ -498,9 +498,9 @@ void FFMpegReaderImplementation::processPacket(AVPacket *packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 FFMpegReaderImplementation::countPacketMs(AVPacket *packet) const {
|
TimeMs FFMpegReaderImplementation::countPacketMs(AVPacket *packet) const {
|
||||||
int64 packetPts = (packet->pts == AV_NOPTS_VALUE) ? packet->dts : packet->pts;
|
int64 packetPts = (packet->pts == AV_NOPTS_VALUE) ? packet->dts : packet->pts;
|
||||||
int64 packetMs = (packetPts * 1000LL * _fmtContext->streams[packet->stream_index]->time_base.num) / _fmtContext->streams[packet->stream_index]->time_base.den;
|
TimeMs packetMs = (packetPts * 1000LL * _fmtContext->streams[packet->stream_index]->time_base.num) / _fmtContext->streams[packet->stream_index]->time_base.den;
|
||||||
return packetMs;
|
return packetMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,14 @@ class FFMpegReaderImplementation : public ReaderImplementation {
|
||||||
public:
|
public:
|
||||||
FFMpegReaderImplementation(FileLocation *location, QByteArray *data, uint64 playId);
|
FFMpegReaderImplementation(FileLocation *location, QByteArray *data, uint64 playId);
|
||||||
|
|
||||||
ReadResult readFramesTill(int64 frameMs, uint64 systemMs) override;
|
ReadResult readFramesTill(TimeMs frameMs, TimeMs systemMs) override;
|
||||||
|
|
||||||
int64 frameRealTime() const override;
|
TimeMs frameRealTime() const override;
|
||||||
uint64 framePresentationTime() const override;
|
TimeMs framePresentationTime() const override;
|
||||||
|
|
||||||
bool renderFrame(QImage &to, bool &hasAlpha, const QSize &size) override;
|
bool renderFrame(QImage &to, bool &hasAlpha, const QSize &size) override;
|
||||||
|
|
||||||
int64 durationMs() const override;
|
TimeMs durationMs() const override;
|
||||||
bool hasAudio() const override {
|
bool hasAudio() const override {
|
||||||
return (_audioStreamId >= 0);
|
return (_audioStreamId >= 0);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ private:
|
||||||
};
|
};
|
||||||
PacketResult readPacket(AVPacket *packet);
|
PacketResult readPacket(AVPacket *packet);
|
||||||
void processPacket(AVPacket *packet);
|
void processPacket(AVPacket *packet);
|
||||||
int64 countPacketMs(AVPacket *packet) const;
|
TimeMs countPacketMs(AVPacket *packet) const;
|
||||||
PacketResult readAndProcessPacket();
|
PacketResult readAndProcessPacket();
|
||||||
|
|
||||||
enum class Rotation {
|
enum class Rotation {
|
||||||
|
@ -107,8 +107,8 @@ private:
|
||||||
|
|
||||||
int _audioStreamId = -1;
|
int _audioStreamId = -1;
|
||||||
uint64 _playId = 0;
|
uint64 _playId = 0;
|
||||||
int64 _lastReadVideoMs = 0;
|
TimeMs _lastReadVideoMs = 0;
|
||||||
int64 _lastReadAudioMs = 0;
|
TimeMs _lastReadAudioMs = 0;
|
||||||
|
|
||||||
QQueue<FFMpeg::AVPacketDataWrap> _packetQueue;
|
QQueue<FFMpeg::AVPacketDataWrap> _packetQueue;
|
||||||
AVPacket _packetNull; // for final decoding
|
AVPacket _packetNull; // for final decoding
|
||||||
|
@ -121,12 +121,12 @@ private:
|
||||||
SwsContext *_swsContext = nullptr;
|
SwsContext *_swsContext = nullptr;
|
||||||
QSize _swsSize;
|
QSize _swsSize;
|
||||||
|
|
||||||
int64 _frameMs = 0;
|
TimeMs _frameMs = 0;
|
||||||
int _nextFrameDelay = 0;
|
int _nextFrameDelay = 0;
|
||||||
int _currentFrameDelay = 0;
|
int _currentFrameDelay = 0;
|
||||||
|
|
||||||
int64 _frameTime = 0;
|
TimeMs _frameTime = 0;
|
||||||
int64 _frameTimeCorrection = 0;
|
TimeMs _frameTimeCorrection = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -44,21 +44,21 @@ public:
|
||||||
EndOfFile,
|
EndOfFile,
|
||||||
};
|
};
|
||||||
// Read frames till current frame will have presentation time > frameMs, systemMs = getms().
|
// Read frames till current frame will have presentation time > frameMs, systemMs = getms().
|
||||||
virtual ReadResult readFramesTill(int64 frameMs, uint64 systemMs) = 0;
|
virtual ReadResult readFramesTill(TimeMs frameMs, TimeMs systemMs) = 0;
|
||||||
|
|
||||||
// Get current frame real and presentation time.
|
// Get current frame real and presentation time.
|
||||||
virtual int64 frameRealTime() const = 0;
|
virtual TimeMs frameRealTime() const = 0;
|
||||||
virtual uint64 framePresentationTime() const = 0;
|
virtual TimeMs framePresentationTime() const = 0;
|
||||||
|
|
||||||
// Render current frame to an image with specific size.
|
// Render current frame to an image with specific size.
|
||||||
virtual bool renderFrame(QImage &to, bool &hasAlpha, const QSize &size) = 0;
|
virtual bool renderFrame(QImage &to, bool &hasAlpha, const QSize &size) = 0;
|
||||||
|
|
||||||
virtual int64 durationMs() const = 0;
|
virtual TimeMs durationMs() const = 0;
|
||||||
virtual bool hasAudio() const = 0;
|
virtual bool hasAudio() const = 0;
|
||||||
virtual void pauseAudio() = 0;
|
virtual void pauseAudio() = 0;
|
||||||
virtual void resumeAudio() = 0;
|
virtual void resumeAudio() = 0;
|
||||||
|
|
||||||
virtual bool start(Mode mode, int64 &positionMs) = 0;
|
virtual bool start(Mode mode, TimeMs &positionMs) = 0;
|
||||||
virtual ~ReaderImplementation() {
|
virtual ~ReaderImplementation() {
|
||||||
}
|
}
|
||||||
int64 dataSize() const {
|
int64 dataSize() const {
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace internal {
|
||||||
QtGifReaderImplementation::QtGifReaderImplementation(FileLocation *location, QByteArray *data) : ReaderImplementation(location, data) {
|
QtGifReaderImplementation::QtGifReaderImplementation(FileLocation *location, QByteArray *data) : ReaderImplementation(location, data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReaderImplementation::ReadResult QtGifReaderImplementation::readFramesTill(int64 frameMs, uint64 systemMs) {
|
ReaderImplementation::ReadResult QtGifReaderImplementation::readFramesTill(TimeMs frameMs, TimeMs systemMs) {
|
||||||
if (!_frame.isNull() && _frameTime > frameMs) {
|
if (!_frame.isNull() && _frameTime > frameMs) {
|
||||||
return ReadResult::Success;
|
return ReadResult::Success;
|
||||||
}
|
}
|
||||||
|
@ -43,12 +43,12 @@ ReaderImplementation::ReadResult QtGifReaderImplementation::readFramesTill(int64
|
||||||
return readResult;
|
return readResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 QtGifReaderImplementation::frameRealTime() const {
|
TimeMs QtGifReaderImplementation::frameRealTime() const {
|
||||||
return _frameRealTime;
|
return _frameRealTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 QtGifReaderImplementation::framePresentationTime() const {
|
TimeMs QtGifReaderImplementation::framePresentationTime() const {
|
||||||
return static_cast<uint64>(qMax(_frameTime, 0LL));
|
return qMax(_frameTime, 0LL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReaderImplementation::ReadResult QtGifReaderImplementation::readNextFrame() {
|
ReaderImplementation::ReadResult QtGifReaderImplementation::readNextFrame() {
|
||||||
|
@ -95,7 +95,7 @@ bool QtGifReaderImplementation::renderFrame(QImage &to, bool &hasAlpha, const QS
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 QtGifReaderImplementation::durationMs() const {
|
TimeMs QtGifReaderImplementation::durationMs() const {
|
||||||
return 0; // not supported
|
return 0; // not supported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,14 +31,14 @@ public:
|
||||||
|
|
||||||
QtGifReaderImplementation(FileLocation *location, QByteArray *data);
|
QtGifReaderImplementation(FileLocation *location, QByteArray *data);
|
||||||
|
|
||||||
ReadResult readFramesTill(int64 frameMs, uint64 systemMs) override;
|
ReadResult readFramesTill(TimeMs frameMs, TimeMs systemMs) override;
|
||||||
|
|
||||||
int64 frameRealTime() const override;
|
TimeMs frameRealTime() const override;
|
||||||
uint64 framePresentationTime() const override;
|
TimeMs framePresentationTime() const override;
|
||||||
|
|
||||||
bool renderFrame(QImage &to, bool &hasAlpha, const QSize &size) override;
|
bool renderFrame(QImage &to, bool &hasAlpha, const QSize &size) override;
|
||||||
|
|
||||||
int64 durationMs() const override;
|
TimeMs durationMs() const override;
|
||||||
bool hasAudio() const override {
|
bool hasAudio() const override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
void resumeAudio() override {
|
void resumeAudio() override {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start(Mode mode, int64 &positionMs) override;
|
bool start(Mode mode, TimeMs &positionMs) override;
|
||||||
|
|
||||||
~QtGifReaderImplementation();
|
~QtGifReaderImplementation();
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ private:
|
||||||
|
|
||||||
QImageReader *_reader = nullptr;
|
QImageReader *_reader = nullptr;
|
||||||
int _framesLeft = 0;
|
int _framesLeft = 0;
|
||||||
int64 _frameRealTime = 0;
|
TimeMs _frameRealTime = 0;
|
||||||
int64 _frameTime = 0;
|
TimeMs _frameTime = 0;
|
||||||
int _frameDelay = 0;
|
int _frameDelay = 0;
|
||||||
QImage _frame;
|
QImage _frame;
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ void Reader::start(int32 framew, int32 frameh, int32 outerw, int32 outerh, Image
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap Reader::current(int32 framew, int32 frameh, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners, uint64 ms) {
|
QPixmap Reader::current(int32 framew, int32 frameh, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners, TimeMs ms) {
|
||||||
auto frame = frameToShow();
|
auto frame = frameToShow();
|
||||||
t_assert(frame != nullptr);
|
t_assert(frame != nullptr);
|
||||||
|
|
||||||
|
@ -271,14 +271,14 @@ bool Reader::hasAudio() const {
|
||||||
return ready() ? _hasAudio : false;
|
return ready() ? _hasAudio : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 Reader::getPositionMs() const {
|
TimeMs Reader::getPositionMs() const {
|
||||||
if (auto frame = frameToShow()) {
|
if (auto frame = frameToShow()) {
|
||||||
return frame->positionMs;
|
return frame->positionMs;
|
||||||
}
|
}
|
||||||
return _seekPositionMs;
|
return _seekPositionMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 Reader::getDurationMs() const {
|
TimeMs Reader::getDurationMs() const {
|
||||||
return ready() ? _durationMs : 0;
|
return ready() ? _durationMs : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ public:
|
||||||
_accessed = true;
|
_accessed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessResult start(uint64 ms) {
|
ProcessResult start(TimeMs ms) {
|
||||||
if (!_implementation && !init()) {
|
if (!_implementation && !init()) {
|
||||||
return error();
|
return error();
|
||||||
}
|
}
|
||||||
|
@ -393,7 +393,7 @@ public:
|
||||||
return ProcessResult::Wait;
|
return ProcessResult::Wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessResult process(uint64 ms) { // -1 - do nothing, 0 - update, 1 - reinit
|
ProcessResult process(TimeMs ms) { // -1 - do nothing, 0 - update, 1 - reinit
|
||||||
if (_state == State::Error) {
|
if (_state == State::Error) {
|
||||||
return ProcessResult::Error;
|
return ProcessResult::Error;
|
||||||
} else if (_state == State::Finished) {
|
} else if (_state == State::Finished) {
|
||||||
|
@ -416,7 +416,7 @@ public:
|
||||||
return ProcessResult::Wait;
|
return ProcessResult::Wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessResult finishProcess(uint64 ms) {
|
ProcessResult finishProcess(TimeMs ms) {
|
||||||
auto frameMs = _seekPositionMs + ms - _animationStarted;
|
auto frameMs = _seekPositionMs + ms - _animationStarted;
|
||||||
auto readResult = _implementation->readFramesTill(frameMs, ms);
|
auto readResult = _implementation->readFramesTill(frameMs, ms);
|
||||||
if (readResult == internal::ReaderImplementation::ReadResult::EndOfFile) {
|
if (readResult == internal::ReaderImplementation::ReadResult::EndOfFile) {
|
||||||
|
@ -428,7 +428,7 @@ public:
|
||||||
}
|
}
|
||||||
_nextFramePositionMs = _implementation->frameRealTime();
|
_nextFramePositionMs = _implementation->frameRealTime();
|
||||||
_nextFrameWhen = _animationStarted + _implementation->framePresentationTime();
|
_nextFrameWhen = _animationStarted + _implementation->framePresentationTime();
|
||||||
if (static_cast<int64>(_nextFrameWhen) > _seekPositionMs) {
|
if (_nextFrameWhen > _seekPositionMs) {
|
||||||
_nextFrameWhen -= _seekPositionMs;
|
_nextFrameWhen -= _seekPositionMs;
|
||||||
} else {
|
} else {
|
||||||
_nextFrameWhen = 1;
|
_nextFrameWhen = 1;
|
||||||
|
@ -477,21 +477,21 @@ public:
|
||||||
return _implementation->start(implementationMode(), _seekPositionMs);
|
return _implementation->start(implementationMode(), _seekPositionMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startedAt(uint64 ms) {
|
void startedAt(TimeMs ms) {
|
||||||
_animationStarted = _nextFrameWhen = ms;
|
_animationStarted = _nextFrameWhen = ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pauseVideo(uint64 ms) {
|
void pauseVideo(TimeMs ms) {
|
||||||
if (_videoPausedAtMs) return; // Paused already.
|
if (_videoPausedAtMs) return; // Paused already.
|
||||||
|
|
||||||
_videoPausedAtMs = ms;
|
_videoPausedAtMs = ms;
|
||||||
_implementation->pauseAudio();
|
_implementation->pauseAudio();
|
||||||
}
|
}
|
||||||
|
|
||||||
void resumeVideo(uint64 ms) {
|
void resumeVideo(TimeMs ms) {
|
||||||
if (!_videoPausedAtMs) return; // Not paused.
|
if (!_videoPausedAtMs) return; // Not paused.
|
||||||
|
|
||||||
int64 delta = static_cast<int64>(ms) - static_cast<int64>(_videoPausedAtMs);
|
auto delta = ms - _videoPausedAtMs;
|
||||||
_animationStarted += delta;
|
_animationStarted += delta;
|
||||||
_nextFrameWhen += delta;
|
_nextFrameWhen += delta;
|
||||||
|
|
||||||
|
@ -527,7 +527,7 @@ private:
|
||||||
State _state = State::Reading;
|
State _state = State::Reading;
|
||||||
Reader::Mode _mode;
|
Reader::Mode _mode;
|
||||||
uint64 _playId;
|
uint64 _playId;
|
||||||
int64 _seekPositionMs = 0;
|
TimeMs _seekPositionMs = 0;
|
||||||
|
|
||||||
QByteArray _data;
|
QByteArray _data;
|
||||||
std_::unique_ptr<FileLocation> _location;
|
std_::unique_ptr<FileLocation> _location;
|
||||||
|
@ -541,10 +541,10 @@ private:
|
||||||
QPixmap pix;
|
QPixmap pix;
|
||||||
QImage original, cache;
|
QImage original, cache;
|
||||||
bool alpha = true;
|
bool alpha = true;
|
||||||
uint64 when = 0;
|
TimeMs when = 0;
|
||||||
|
|
||||||
// Counted from the end, so that positionMs <= durationMs despite keep up delays.
|
// Counted from the end, so that positionMs <= durationMs despite keep up delays.
|
||||||
int64 positionMs = 0;
|
TimeMs positionMs = 0;
|
||||||
};
|
};
|
||||||
Frame _frames[3];
|
Frame _frames[3];
|
||||||
int _frame = 0;
|
int _frame = 0;
|
||||||
|
@ -556,14 +556,14 @@ private:
|
||||||
int _height = 0;
|
int _height = 0;
|
||||||
|
|
||||||
bool _hasAudio = false;
|
bool _hasAudio = false;
|
||||||
int64 _durationMs = 0;
|
TimeMs _durationMs = 0;
|
||||||
uint64 _animationStarted = 0;
|
TimeMs _animationStarted = 0;
|
||||||
uint64 _nextFrameWhen = 0;
|
TimeMs _nextFrameWhen = 0;
|
||||||
int64 _nextFramePositionMs = 0;
|
TimeMs _nextFramePositionMs = 0;
|
||||||
|
|
||||||
bool _autoPausedGif = false;
|
bool _autoPausedGif = false;
|
||||||
bool _started = false;
|
bool _started = false;
|
||||||
uint64 _videoPausedAtMs = 0;
|
TimeMs _videoPausedAtMs = 0;
|
||||||
|
|
||||||
friend class Manager;
|
friend class Manager;
|
||||||
|
|
||||||
|
@ -630,7 +630,7 @@ Manager::ReaderPointers::const_iterator Manager::constUnsafeFindReaderPointer(Re
|
||||||
return (it == _readerPointers.cend() || it.key()->_private == reader) ? it : _readerPointers.cend();
|
return (it == _readerPointers.cend() || it.key()->_private == reader) ? it : _readerPointers.cend();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::handleProcessResult(ReaderPrivate *reader, ProcessResult result, uint64 ms) {
|
bool Manager::handleProcessResult(ReaderPrivate *reader, ProcessResult result, TimeMs ms) {
|
||||||
QMutexLocker lock(&_readerPointersMutex);
|
QMutexLocker lock(&_readerPointersMutex);
|
||||||
auto it = unsafeFindReaderPointer(reader);
|
auto it = unsafeFindReaderPointer(reader);
|
||||||
if (result == ProcessResult::Error) {
|
if (result == ProcessResult::Error) {
|
||||||
|
@ -692,7 +692,7 @@ bool Manager::handleProcessResult(ReaderPrivate *reader, ProcessResult result, u
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::ResultHandleState Manager::handleResult(ReaderPrivate *reader, ProcessResult result, uint64 ms) {
|
Manager::ResultHandleState Manager::handleResult(ReaderPrivate *reader, ProcessResult result, TimeMs ms) {
|
||||||
if (!handleProcessResult(reader, result, ms)) {
|
if (!handleProcessResult(reader, result, ms)) {
|
||||||
_loadLevel.fetchAndAddRelaxed(-1 * (reader->_width > 0 ? reader->_width * reader->_height : AverageGifSize));
|
_loadLevel.fetchAndAddRelaxed(-1 * (reader->_width > 0 ? reader->_width * reader->_height : AverageGifSize));
|
||||||
delete reader;
|
delete reader;
|
||||||
|
@ -736,7 +736,7 @@ void Manager::process() {
|
||||||
_processingInThread = thread();
|
_processingInThread = thread();
|
||||||
|
|
||||||
bool checkAllReaders = false;
|
bool checkAllReaders = false;
|
||||||
uint64 ms = getms(), minms = ms + 86400 * 1000ULL;
|
auto ms = getms(), minms = ms + 86400 * 1000LL;
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&_readerPointersMutex);
|
QMutexLocker lock(&_readerPointersMutex);
|
||||||
for (auto it = _readerPointers.begin(), e = _readerPointers.end(); it != e; ++it) {
|
for (auto it = _readerPointers.begin(), e = _readerPointers.end(); it != e; ++it) {
|
||||||
|
|
|
@ -59,7 +59,7 @@ public:
|
||||||
Video,
|
Video,
|
||||||
};
|
};
|
||||||
|
|
||||||
Reader(const FileLocation &location, const QByteArray &data, Callback &&callback, Mode mode = Mode::Gif, int64 seekMs = 0);
|
Reader(const FileLocation &location, const QByteArray &data, Callback &&callback, Mode mode = Mode::Gif, TimeMs seekMs = 0);
|
||||||
static void callback(Reader *reader, int threadIndex, Notification notification); // reader can be deleted
|
static void callback(Reader *reader, int threadIndex, Notification notification); // reader can be deleted
|
||||||
|
|
||||||
void setAutoplay() {
|
void setAutoplay() {
|
||||||
|
@ -72,12 +72,12 @@ public:
|
||||||
uint64 playId() const {
|
uint64 playId() const {
|
||||||
return _playId;
|
return _playId;
|
||||||
}
|
}
|
||||||
int64 seekPositionMs() const {
|
TimeMs seekPositionMs() const {
|
||||||
return _seekPositionMs;
|
return _seekPositionMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(int framew, int frameh, int outerw, int outerh, ImageRoundRadius radius, ImageRoundCorners corners);
|
void start(int framew, int frameh, int outerw, int outerh, ImageRoundRadius radius, ImageRoundCorners corners);
|
||||||
QPixmap current(int framew, int frameh, int outerw, int outerh, ImageRoundRadius radius, ImageRoundCorners corners, uint64 ms);
|
QPixmap current(int framew, int frameh, int outerw, int outerh, ImageRoundRadius radius, ImageRoundCorners corners, TimeMs ms);
|
||||||
QPixmap frameOriginal() const {
|
QPixmap frameOriginal() const {
|
||||||
if (auto frame = frameToShow()) {
|
if (auto frame = frameToShow()) {
|
||||||
auto result = QPixmap::fromImage(frame->original);
|
auto result = QPixmap::fromImage(frame->original);
|
||||||
|
@ -109,8 +109,8 @@ public:
|
||||||
bool ready() const;
|
bool ready() const;
|
||||||
|
|
||||||
bool hasAudio() const;
|
bool hasAudio() const;
|
||||||
int64 getPositionMs() const;
|
TimeMs getPositionMs() const;
|
||||||
int64 getDurationMs() const;
|
TimeMs getDurationMs() const;
|
||||||
void pauseResumeVideo();
|
void pauseResumeVideo();
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -132,8 +132,8 @@ private:
|
||||||
|
|
||||||
uint64 _playId;
|
uint64 _playId;
|
||||||
bool _hasAudio = false;
|
bool _hasAudio = false;
|
||||||
int64 _durationMs = 0;
|
TimeMs _durationMs = 0;
|
||||||
int64 _seekPositionMs = 0;
|
TimeMs _seekPositionMs = 0;
|
||||||
|
|
||||||
mutable int _width = 0;
|
mutable int _width = 0;
|
||||||
mutable int _height = 0;
|
mutable int _height = 0;
|
||||||
|
@ -152,7 +152,7 @@ private:
|
||||||
|
|
||||||
// Should be counted from the end,
|
// Should be counted from the end,
|
||||||
// so that positionMs <= _durationMs.
|
// so that positionMs <= _durationMs.
|
||||||
int64 positionMs = 0;
|
TimeMs positionMs = 0;
|
||||||
};
|
};
|
||||||
mutable Frame _frames[3];
|
mutable Frame _frames[3];
|
||||||
Frame *frameToShow(int *index = 0) const; // 0 means not ready
|
Frame *frameToShow(int *index = 0) const; // 0 means not ready
|
||||||
|
@ -225,16 +225,16 @@ private:
|
||||||
ReaderPointers::const_iterator constUnsafeFindReaderPointer(ReaderPrivate *reader) const;
|
ReaderPointers::const_iterator constUnsafeFindReaderPointer(ReaderPrivate *reader) const;
|
||||||
ReaderPointers::iterator unsafeFindReaderPointer(ReaderPrivate *reader);
|
ReaderPointers::iterator unsafeFindReaderPointer(ReaderPrivate *reader);
|
||||||
|
|
||||||
bool handleProcessResult(ReaderPrivate *reader, ProcessResult result, uint64 ms);
|
bool handleProcessResult(ReaderPrivate *reader, ProcessResult result, TimeMs ms);
|
||||||
|
|
||||||
enum ResultHandleState {
|
enum ResultHandleState {
|
||||||
ResultHandleRemove,
|
ResultHandleRemove,
|
||||||
ResultHandleStop,
|
ResultHandleStop,
|
||||||
ResultHandleContinue,
|
ResultHandleContinue,
|
||||||
};
|
};
|
||||||
ResultHandleState handleResult(ReaderPrivate *reader, ProcessResult result, uint64 ms);
|
ResultHandleState handleResult(ReaderPrivate *reader, ProcessResult result, TimeMs ms);
|
||||||
|
|
||||||
typedef QMap<ReaderPrivate*, uint64> Readers;
|
typedef QMap<ReaderPrivate*, TimeMs> Readers;
|
||||||
Readers _readers;
|
Readers _readers;
|
||||||
|
|
||||||
QTimer _timer;
|
QTimer _timer;
|
||||||
|
|
|
@ -144,7 +144,7 @@ void CoverWidget::setCloseCallback(ButtonCallback &&callback) {
|
||||||
void CoverWidget::handleSeekProgress(float64 progress) {
|
void CoverWidget::handleSeekProgress(float64 progress) {
|
||||||
if (!_lastDurationMs) return;
|
if (!_lastDurationMs) return;
|
||||||
|
|
||||||
auto positionMs = snap(static_cast<int64>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
auto positionMs = snap(static_cast<TimeMs>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
||||||
if (_seekPositionMs != positionMs) {
|
if (_seekPositionMs != positionMs) {
|
||||||
_seekPositionMs = positionMs;
|
_seekPositionMs = positionMs;
|
||||||
updateTimeLabel();
|
updateTimeLabel();
|
||||||
|
@ -157,7 +157,7 @@ void CoverWidget::handleSeekProgress(float64 progress) {
|
||||||
void CoverWidget::handleSeekFinished(float64 progress) {
|
void CoverWidget::handleSeekFinished(float64 progress) {
|
||||||
if (!_lastDurationMs) return;
|
if (!_lastDurationMs) return;
|
||||||
|
|
||||||
auto positionMs = snap(static_cast<int64>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
auto positionMs = snap(static_cast<TimeMs>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
||||||
_seekPositionMs = -1;
|
_seekPositionMs = -1;
|
||||||
|
|
||||||
AudioMsgId playing;
|
AudioMsgId playing;
|
||||||
|
|
|
@ -73,8 +73,8 @@ private:
|
||||||
void updateTimeText(const AudioMsgId &audioId, const AudioPlaybackState &playbackState);
|
void updateTimeText(const AudioMsgId &audioId, const AudioPlaybackState &playbackState);
|
||||||
void updateTimeLabel();
|
void updateTimeLabel();
|
||||||
|
|
||||||
int64 _seekPositionMs = -1;
|
TimeMs _seekPositionMs = -1;
|
||||||
int64 _lastDurationMs = 0;
|
TimeMs _lastDurationMs = 0;
|
||||||
QString _time;
|
QString _time;
|
||||||
|
|
||||||
class PlayButton;
|
class PlayButton;
|
||||||
|
|
|
@ -181,7 +181,7 @@ void Widget::volumeWidgetCreated(VolumeWidget *widget) {
|
||||||
void Widget::handleSeekProgress(float64 progress) {
|
void Widget::handleSeekProgress(float64 progress) {
|
||||||
if (!_lastDurationMs) return;
|
if (!_lastDurationMs) return;
|
||||||
|
|
||||||
auto positionMs = snap(static_cast<int64>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
auto positionMs = snap(static_cast<TimeMs>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
||||||
if (_seekPositionMs != positionMs) {
|
if (_seekPositionMs != positionMs) {
|
||||||
_seekPositionMs = positionMs;
|
_seekPositionMs = positionMs;
|
||||||
updateTimeLabel();
|
updateTimeLabel();
|
||||||
|
@ -194,7 +194,7 @@ void Widget::handleSeekProgress(float64 progress) {
|
||||||
void Widget::handleSeekFinished(float64 progress) {
|
void Widget::handleSeekFinished(float64 progress) {
|
||||||
if (!_lastDurationMs) return;
|
if (!_lastDurationMs) return;
|
||||||
|
|
||||||
auto positionMs = snap(static_cast<int64>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
auto positionMs = snap(static_cast<TimeMs>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
||||||
_seekPositionMs = -1;
|
_seekPositionMs = -1;
|
||||||
|
|
||||||
AudioMsgId playing;
|
AudioMsgId playing;
|
||||||
|
|
|
@ -86,8 +86,8 @@ private:
|
||||||
void updateTimeText(const AudioMsgId &audioId, const AudioPlaybackState &playbackState);
|
void updateTimeText(const AudioMsgId &audioId, const AudioPlaybackState &playbackState);
|
||||||
void updateTimeLabel();
|
void updateTimeLabel();
|
||||||
|
|
||||||
int64 _seekPositionMs = -1;
|
TimeMs _seekPositionMs = -1;
|
||||||
int64 _lastDurationMs = 0;
|
TimeMs _lastDurationMs = 0;
|
||||||
QString _time;
|
QString _time;
|
||||||
|
|
||||||
class PlayButton;
|
class PlayButton;
|
||||||
|
|
|
@ -62,7 +62,7 @@ Controller::Controller(QWidget *parent) : TWidget(parent)
|
||||||
void Controller::handleSeekProgress(float64 progress) {
|
void Controller::handleSeekProgress(float64 progress) {
|
||||||
if (!_lastDurationMs) return;
|
if (!_lastDurationMs) return;
|
||||||
|
|
||||||
auto positionMs = snap(static_cast<int64>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
auto positionMs = snap(static_cast<TimeMs>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
||||||
if (_seekPositionMs != positionMs) {
|
if (_seekPositionMs != positionMs) {
|
||||||
_seekPositionMs = positionMs;
|
_seekPositionMs = positionMs;
|
||||||
refreshTimeTexts();
|
refreshTimeTexts();
|
||||||
|
@ -73,7 +73,7 @@ void Controller::handleSeekProgress(float64 progress) {
|
||||||
void Controller::handleSeekFinished(float64 progress) {
|
void Controller::handleSeekFinished(float64 progress) {
|
||||||
if (!_lastDurationMs) return;
|
if (!_lastDurationMs) return;
|
||||||
|
|
||||||
auto positionMs = snap(static_cast<int64>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
auto positionMs = snap(static_cast<TimeMs>(progress * _lastDurationMs), 0LL, _lastDurationMs);
|
||||||
_seekPositionMs = -1;
|
_seekPositionMs = -1;
|
||||||
emit seekFinished(positionMs);
|
emit seekFinished(positionMs);
|
||||||
refreshTimeTexts();
|
refreshTimeTexts();
|
||||||
|
|
|
@ -54,8 +54,8 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void playPressed();
|
void playPressed();
|
||||||
void pausePressed();
|
void pausePressed();
|
||||||
void seekProgress(int64 positionMs);
|
void seekProgress(TimeMs positionMs);
|
||||||
void seekFinished(int64 positionMs);
|
void seekFinished(TimeMs positionMs);
|
||||||
void volumeChanged(float64 volume);
|
void volumeChanged(float64 volume);
|
||||||
void toFullScreenPressed();
|
void toFullScreenPressed();
|
||||||
void fromFullScreenPressed();
|
void fromFullScreenPressed();
|
||||||
|
@ -80,8 +80,8 @@ private:
|
||||||
|
|
||||||
bool _showPause = false;
|
bool _showPause = false;
|
||||||
QString _timeAlready, _timeLeft;
|
QString _timeAlready, _timeLeft;
|
||||||
int64 _seekPositionMs = -1;
|
TimeMs _seekPositionMs = -1;
|
||||||
int64 _lastDurationMs = 0;
|
TimeMs _lastDurationMs = 0;
|
||||||
|
|
||||||
ChildWidget<Ui::IconButton> _playPauseResume;
|
ChildWidget<Ui::IconButton> _playPauseResume;
|
||||||
ChildWidget<Playback> _playback;
|
ChildWidget<Playback> _playback;
|
||||||
|
|
|
@ -66,7 +66,7 @@ private:
|
||||||
Ui::ContinuousSlider *_slider;
|
Ui::ContinuousSlider *_slider;
|
||||||
|
|
||||||
int64 _position = 0;
|
int64 _position = 0;
|
||||||
int64 _duration = 0;
|
TimeMs _duration = 0;
|
||||||
|
|
||||||
bool _playing = false;
|
bool _playing = false;
|
||||||
|
|
||||||
|
|
|
@ -394,10 +394,10 @@ void MediaView::updateActions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaView::step_state(uint64 ms, bool timer) {
|
void MediaView::step_state(TimeMs ms, bool timer) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
for (Showing::iterator i = _animations.begin(); i != _animations.end();) {
|
for (Showing::iterator i = _animations.begin(); i != _animations.end();) {
|
||||||
int64 start = i.value();
|
TimeMs start = i.value();
|
||||||
switch (i.key()) {
|
switch (i.key()) {
|
||||||
case OverLeftNav: update(_leftNav); break;
|
case OverLeftNav: update(_leftNav); break;
|
||||||
case OverRightNav: update(_rightNav); break;
|
case OverRightNav: update(_rightNav); break;
|
||||||
|
@ -477,11 +477,11 @@ void MediaView::radialStart() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 MediaView::radialTimeShift() const {
|
TimeMs MediaView::radialTimeShift() const {
|
||||||
return _photo ? st::radialDuration : 0;
|
return _photo ? st::radialDuration : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaView::step_radial(uint64 ms, bool timer) {
|
void MediaView::step_radial(TimeMs ms, bool timer) {
|
||||||
if (!_doc && !_photo) {
|
if (!_doc && !_photo) {
|
||||||
_radial.stop();
|
_radial.stop();
|
||||||
return;
|
return;
|
||||||
|
@ -1373,8 +1373,8 @@ void MediaView::createClipController() {
|
||||||
|
|
||||||
connect(_clipController, SIGNAL(playPressed()), this, SLOT(onVideoPauseResume()));
|
connect(_clipController, SIGNAL(playPressed()), this, SLOT(onVideoPauseResume()));
|
||||||
connect(_clipController, SIGNAL(pausePressed()), this, SLOT(onVideoPauseResume()));
|
connect(_clipController, SIGNAL(pausePressed()), this, SLOT(onVideoPauseResume()));
|
||||||
connect(_clipController, SIGNAL(seekProgress(int64)), this, SLOT(onVideoSeekProgress(int64)));
|
connect(_clipController, SIGNAL(seekProgress(TimeMs)), this, SLOT(onVideoSeekProgress(TimeMs)));
|
||||||
connect(_clipController, SIGNAL(seekFinished(int64)), this, SLOT(onVideoSeekFinished(int64)));
|
connect(_clipController, SIGNAL(seekFinished(TimeMs)), this, SLOT(onVideoSeekFinished(TimeMs)));
|
||||||
connect(_clipController, SIGNAL(volumeChanged(float64)), this, SLOT(onVideoVolumeChanged(float64)));
|
connect(_clipController, SIGNAL(volumeChanged(float64)), this, SLOT(onVideoVolumeChanged(float64)));
|
||||||
connect(_clipController, SIGNAL(toFullScreenPressed()), this, SLOT(onVideoToggleFullScreen()));
|
connect(_clipController, SIGNAL(toFullScreenPressed()), this, SLOT(onVideoToggleFullScreen()));
|
||||||
connect(_clipController, SIGNAL(fromFullScreenPressed()), this, SLOT(onVideoToggleFullScreen()));
|
connect(_clipController, SIGNAL(fromFullScreenPressed()), this, SLOT(onVideoToggleFullScreen()));
|
||||||
|
@ -1418,7 +1418,7 @@ void MediaView::onVideoPauseResume() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaView::restartVideoAtSeekPosition(int64 positionMs) {
|
void MediaView::restartVideoAtSeekPosition(TimeMs positionMs) {
|
||||||
_autoplayVideoDocument = _doc;
|
_autoplayVideoDocument = _doc;
|
||||||
|
|
||||||
if (_current.isNull()) {
|
if (_current.isNull()) {
|
||||||
|
@ -1440,13 +1440,13 @@ void MediaView::restartVideoAtSeekPosition(int64 positionMs) {
|
||||||
updateVideoPlaybackState(state);
|
updateVideoPlaybackState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaView::onVideoSeekProgress(int64 positionMs) {
|
void MediaView::onVideoSeekProgress(TimeMs positionMs) {
|
||||||
if (!_videoPaused && !_videoStopped) {
|
if (!_videoPaused && !_videoStopped) {
|
||||||
onVideoPauseResume();
|
onVideoPauseResume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaView::onVideoSeekFinished(int64 positionMs) {
|
void MediaView::onVideoSeekFinished(TimeMs positionMs) {
|
||||||
restartVideoAtSeekPosition(positionMs);
|
restartVideoAtSeekPosition(positionMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1516,7 +1516,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
|
||||||
QRegion region(e->region());
|
QRegion region(e->region());
|
||||||
QVector<QRect> rs(region.rects());
|
QVector<QRect> rs(region.rects());
|
||||||
|
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
|
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
|
@ -1624,7 +1624,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
if (_full >= 1) {
|
if (_full >= 1) {
|
||||||
uint64 nextFrame = (dt < st::medviewSaveMsgShowing || hidingDt >= 0) ? int(AnimationTimerDelta) : (st::medviewSaveMsgShowing + st::medviewSaveMsgShown + 1 - dt);
|
auto nextFrame = (dt < st::medviewSaveMsgShowing || hidingDt >= 0) ? int(AnimationTimerDelta) : (st::medviewSaveMsgShowing + st::medviewSaveMsgShown + 1 - dt);
|
||||||
_saveMsgUpdater.start(nextFrame);
|
_saveMsgUpdater.start(nextFrame);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -120,8 +120,8 @@ private slots:
|
||||||
void updateImage();
|
void updateImage();
|
||||||
|
|
||||||
void onVideoPauseResume();
|
void onVideoPauseResume();
|
||||||
void onVideoSeekProgress(int64 positionMs);
|
void onVideoSeekProgress(TimeMs positionMs);
|
||||||
void onVideoSeekFinished(int64 positionMs);
|
void onVideoSeekFinished(TimeMs positionMs);
|
||||||
void onVideoVolumeChanged(float64 volume);
|
void onVideoVolumeChanged(float64 volume);
|
||||||
void onVideoToggleFullScreen();
|
void onVideoToggleFullScreen();
|
||||||
void onVideoPlayProgress(const AudioMsgId &audioId);
|
void onVideoPlayProgress(const AudioMsgId &audioId);
|
||||||
|
@ -147,7 +147,7 @@ private:
|
||||||
|
|
||||||
void updateVideoPlaybackState(const AudioPlaybackState &state);
|
void updateVideoPlaybackState(const AudioPlaybackState &state);
|
||||||
void updateSilentVideoPlaybackState();
|
void updateSilentVideoPlaybackState();
|
||||||
void restartVideoAtSeekPosition(int64 positionMs);
|
void restartVideoAtSeekPosition(TimeMs positionMs);
|
||||||
|
|
||||||
void createClipController();
|
void createClipController();
|
||||||
void setClipControllerGeometry();
|
void setClipControllerGeometry();
|
||||||
|
@ -160,7 +160,7 @@ private:
|
||||||
bool radialLoading() const;
|
bool radialLoading() const;
|
||||||
QRect radialRect() const;
|
QRect radialRect() const;
|
||||||
void radialStart();
|
void radialStart();
|
||||||
uint64 radialTimeShift() const;
|
TimeMs radialTimeShift() const;
|
||||||
|
|
||||||
// Computes the last OverviewChatPhotos PhotoData* from _history or _migrated.
|
// Computes the last OverviewChatPhotos PhotoData* from _history or _migrated.
|
||||||
struct LastChatPhoto {
|
struct LastChatPhoto {
|
||||||
|
@ -178,8 +178,8 @@ private:
|
||||||
void updateHeader();
|
void updateHeader();
|
||||||
void snapXY();
|
void snapXY();
|
||||||
|
|
||||||
void step_state(uint64 ms, bool timer);
|
void step_state(TimeMs ms, bool timer);
|
||||||
void step_radial(uint64 ms, bool timer);
|
void step_radial(TimeMs ms, bool timer);
|
||||||
|
|
||||||
void zoomIn();
|
void zoomIn();
|
||||||
void zoomOut();
|
void zoomOut();
|
||||||
|
@ -212,7 +212,7 @@ private:
|
||||||
Text _caption;
|
Text _caption;
|
||||||
QRect _captionRect;
|
QRect _captionRect;
|
||||||
|
|
||||||
uint64 _animStarted;
|
TimeMs _animStarted;
|
||||||
|
|
||||||
int _width = 0;
|
int _width = 0;
|
||||||
int _x = 0, _y = 0, _w = 0, _h = 0;
|
int _x = 0, _y = 0, _w = 0, _h = 0;
|
||||||
|
@ -230,8 +230,8 @@ private:
|
||||||
bool _videoIsSilent = false;
|
bool _videoIsSilent = false;
|
||||||
bool _videoPaused = false;
|
bool _videoPaused = false;
|
||||||
bool _videoStopped = false;
|
bool _videoStopped = false;
|
||||||
int64 _videoPositionMs = 0;
|
TimeMs _videoPositionMs = 0;
|
||||||
int64 _videoDurationMs = 0;
|
TimeMs _videoDurationMs = 0;
|
||||||
int32 _videoFrequencyMs = 1000; // 1000 ms per second.
|
int32 _videoFrequencyMs = 1000; // 1000 ms per second.
|
||||||
|
|
||||||
bool fileShown() const;
|
bool fileShown() const;
|
||||||
|
@ -305,7 +305,7 @@ private:
|
||||||
ControlsHidden,
|
ControlsHidden,
|
||||||
};
|
};
|
||||||
ControlsState _controlsState = ControlsShown;
|
ControlsState _controlsState = ControlsShown;
|
||||||
uint64 _controlsAnimStarted = 0;
|
TimeMs _controlsAnimStarted = 0;
|
||||||
QTimer _controlsHideTimer;
|
QTimer _controlsHideTimer;
|
||||||
anim::fvalue a_cOpacity;
|
anim::fvalue a_cOpacity;
|
||||||
bool _mousePressed = false;
|
bool _mousePressed = false;
|
||||||
|
@ -327,13 +327,13 @@ private:
|
||||||
QPoint _accumScroll;
|
QPoint _accumScroll;
|
||||||
|
|
||||||
QString _saveMsgFilename;
|
QString _saveMsgFilename;
|
||||||
uint64 _saveMsgStarted = 0;
|
TimeMs _saveMsgStarted = 0;
|
||||||
anim::fvalue _saveMsgOpacity = { 0 };
|
anim::fvalue _saveMsgOpacity = { 0 };
|
||||||
QRect _saveMsg;
|
QRect _saveMsg;
|
||||||
QTimer _saveMsgUpdater;
|
QTimer _saveMsgUpdater;
|
||||||
Text _saveMsgText;
|
Text _saveMsgText;
|
||||||
|
|
||||||
typedef QMap<OverState, uint64> Showing;
|
typedef QMap<OverState, TimeMs> Showing;
|
||||||
Showing _animations;
|
Showing _animations;
|
||||||
typedef QMap<OverState, anim::fvalue> ShowingOpacities;
|
typedef QMap<OverState, anim::fvalue> ShowingOpacities;
|
||||||
ShowingOpacities _animOpacities;
|
ShowingOpacities _animOpacities;
|
||||||
|
|
|
@ -478,12 +478,12 @@ ConnectionPrivate::ConnectionPrivate(QThread *thread, Connection *owner, Session
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(this, SIGNAL(needToSendAsync()), sessionData->owner(), SLOT(needToResumeAndSend()), Qt::QueuedConnection);
|
connect(this, SIGNAL(needToSendAsync()), sessionData->owner(), SLOT(needToResumeAndSend()), Qt::QueuedConnection);
|
||||||
connect(this, SIGNAL(sendAnythingAsync(quint64)), sessionData->owner(), SLOT(sendAnything(quint64)), Qt::QueuedConnection);
|
connect(this, SIGNAL(sendAnythingAsync(qint64)), sessionData->owner(), SLOT(sendAnything(qint64)), Qt::QueuedConnection);
|
||||||
connect(this, SIGNAL(sendHttpWaitAsync()), sessionData->owner(), SLOT(sendAnything()), Qt::QueuedConnection);
|
connect(this, SIGNAL(sendHttpWaitAsync()), sessionData->owner(), SLOT(sendAnything()), Qt::QueuedConnection);
|
||||||
connect(this, SIGNAL(sendPongAsync(quint64,quint64)), sessionData->owner(), SLOT(sendPong(quint64,quint64)), Qt::QueuedConnection);
|
connect(this, SIGNAL(sendPongAsync(quint64,quint64)), sessionData->owner(), SLOT(sendPong(quint64,quint64)), Qt::QueuedConnection);
|
||||||
connect(this, SIGNAL(sendMsgsStateInfoAsync(quint64, QByteArray)), sessionData->owner(), SLOT(sendMsgsStateInfo(quint64,QByteArray)), Qt::QueuedConnection);
|
connect(this, SIGNAL(sendMsgsStateInfoAsync(quint64, QByteArray)), sessionData->owner(), SLOT(sendMsgsStateInfo(quint64,QByteArray)), Qt::QueuedConnection);
|
||||||
connect(this, SIGNAL(resendAsync(quint64,quint64,bool,bool)), sessionData->owner(), SLOT(resend(quint64,quint64,bool,bool)), Qt::QueuedConnection);
|
connect(this, SIGNAL(resendAsync(quint64,qint64,bool,bool)), sessionData->owner(), SLOT(resend(quint64,qint64,bool,bool)), Qt::QueuedConnection);
|
||||||
connect(this, SIGNAL(resendManyAsync(QVector<quint64>,quint64,bool,bool)), sessionData->owner(), SLOT(resendMany(QVector<quint64>,quint64,bool,bool)), Qt::QueuedConnection);
|
connect(this, SIGNAL(resendManyAsync(QVector<quint64>,qint64,bool,bool)), sessionData->owner(), SLOT(resendMany(QVector<quint64>,qint64,bool,bool)), Qt::QueuedConnection);
|
||||||
connect(this, SIGNAL(resendAllAsync()), sessionData->owner(), SLOT(resendAll()));
|
connect(this, SIGNAL(resendAllAsync()), sessionData->owner(), SLOT(resendAll()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -780,7 +780,7 @@ void ConnectionPrivate::tryToSend() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pingRequest->msDate = getms(true); // > 0 - can send without container
|
pingRequest->msDate = getms(true); // > 0 - can send without container
|
||||||
_pingSendAt = pingRequest->msDate + (MTPPingSendAfterAuto * 1000ULL);
|
_pingSendAt = pingRequest->msDate + (MTPPingSendAfterAuto * 1000LL);
|
||||||
pingRequest->requestId = 0; // dont add to haveSent / wereAcked maps
|
pingRequest->requestId = 0; // dont add to haveSent / wereAcked maps
|
||||||
|
|
||||||
if (dc == bareDcId(dc) && !prependOnly) { // main session
|
if (dc == bareDcId(dc) && !prependOnly) { // main session
|
||||||
|
@ -1255,11 +1255,11 @@ void ConnectionPrivate::onOldConnection() {
|
||||||
|
|
||||||
void ConnectionPrivate::onPingSender() {
|
void ConnectionPrivate::onPingSender() {
|
||||||
if (_pingId) {
|
if (_pingId) {
|
||||||
if (_pingSendAt + (MTPPingSendAfter - MTPPingSendAfterAuto - 1) * 1000ULL < getms(true)) {
|
if (_pingSendAt + (MTPPingSendAfter - MTPPingSendAfterAuto - 1) * 1000LL < getms(true)) {
|
||||||
LOG(("Could not send ping for MTPPingSendAfter seconds, restarting..."));
|
LOG(("Could not send ping for MTPPingSendAfter seconds, restarting..."));
|
||||||
return restart();
|
return restart();
|
||||||
} else {
|
} else {
|
||||||
_pingSender.start(_pingSendAt + (MTPPingSendAfter - MTPPingSendAfterAuto) * 1000ULL - getms(true));
|
_pingSender.start(_pingSendAt + (MTPPingSendAfter - MTPPingSendAfterAuto) * 1000LL - getms(true));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
emit needToSendAsync();
|
emit needToSendAsync();
|
||||||
|
@ -2257,12 +2257,12 @@ void ConnectionPrivate::handleMsgsStates(const QVector<MTPlong> &ids, const stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionPrivate::resend(quint64 msgId, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
|
void ConnectionPrivate::resend(quint64 msgId, qint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
|
||||||
if (msgId == _pingMsgId) return;
|
if (msgId == _pingMsgId) return;
|
||||||
emit resendAsync(msgId, msCanWait, forceContainer, sendMsgStateInfo);
|
emit resendAsync(msgId, msCanWait, forceContainer, sendMsgStateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionPrivate::resendMany(QVector<quint64> msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
|
void ConnectionPrivate::resendMany(QVector<quint64> msgIds, qint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
|
||||||
for (int32 i = 0, l = msgIds.size(); i < l; ++i) {
|
for (int32 i = 0, l = msgIds.size(); i < l; ++i) {
|
||||||
if (msgIds.at(i) == _pingMsgId) {
|
if (msgIds.at(i) == _pingMsgId) {
|
||||||
msgIds.remove(i);
|
msgIds.remove(i);
|
||||||
|
|
|
@ -96,12 +96,12 @@ signals:
|
||||||
void sessionResetDone();
|
void sessionResetDone();
|
||||||
|
|
||||||
void needToSendAsync();
|
void needToSendAsync();
|
||||||
void sendAnythingAsync(quint64 msWait);
|
void sendAnythingAsync(qint64 msWait);
|
||||||
void sendHttpWaitAsync();
|
void sendHttpWaitAsync();
|
||||||
void sendPongAsync(quint64 msgId, quint64 pingId);
|
void sendPongAsync(quint64 msgId, quint64 pingId);
|
||||||
void sendMsgsStateInfoAsync(quint64 msgId, QByteArray data);
|
void sendMsgsStateInfoAsync(quint64 msgId, QByteArray data);
|
||||||
void resendAsync(quint64 msgId, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo);
|
void resendAsync(quint64 msgId, qint64 msCanWait, bool forceContainer, bool sendMsgStateInfo);
|
||||||
void resendManyAsync(QVector<quint64> msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo);
|
void resendManyAsync(QVector<quint64> msgIds, qint64 msCanWait, bool forceContainer, bool sendMsgStateInfo);
|
||||||
void resendAllAsync();
|
void resendAllAsync();
|
||||||
|
|
||||||
void finished(Connection *connection);
|
void finished(Connection *connection);
|
||||||
|
@ -183,14 +183,14 @@ private:
|
||||||
|
|
||||||
SingleTimer retryTimer; // exp retry timer
|
SingleTimer retryTimer; // exp retry timer
|
||||||
int retryTimeout;
|
int retryTimeout;
|
||||||
quint64 retryWillFinish;
|
qint64 retryWillFinish;
|
||||||
|
|
||||||
SingleTimer oldConnectionTimer;
|
SingleTimer oldConnectionTimer;
|
||||||
bool oldConnection;
|
bool oldConnection;
|
||||||
|
|
||||||
SingleTimer _waitForConnectedTimer, _waitForReceivedTimer, _waitForIPv4Timer;
|
SingleTimer _waitForConnectedTimer, _waitForReceivedTimer, _waitForIPv4Timer;
|
||||||
uint32 _waitForReceived, _waitForConnected;
|
uint32 _waitForReceived, _waitForConnected;
|
||||||
int64 firstSentAt;
|
TimeMs firstSentAt;
|
||||||
|
|
||||||
QVector<MTPlong> ackRequestData, resendRequestData;
|
QVector<MTPlong> ackRequestData, resendRequestData;
|
||||||
|
|
||||||
|
@ -201,12 +201,12 @@ private:
|
||||||
void requestsAcked(const QVector<MTPlong> &ids, bool byResponse = false);
|
void requestsAcked(const QVector<MTPlong> &ids, bool byResponse = false);
|
||||||
|
|
||||||
mtpPingId _pingId, _pingIdToSend;
|
mtpPingId _pingId, _pingIdToSend;
|
||||||
uint64 _pingSendAt;
|
TimeMs _pingSendAt;
|
||||||
mtpMsgId _pingMsgId;
|
mtpMsgId _pingMsgId;
|
||||||
SingleTimer _pingSender;
|
SingleTimer _pingSender;
|
||||||
|
|
||||||
void resend(quint64 msgId, quint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false);
|
void resend(quint64 msgId, qint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false);
|
||||||
void resendMany(QVector<quint64> msgIds, quint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false);
|
void resendMany(QVector<quint64> msgIds, qint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false);
|
||||||
|
|
||||||
template <typename TRequest>
|
template <typename TRequest>
|
||||||
void sendRequestNotSecure(const TRequest &request);
|
void sendRequestNotSecure(const TRequest &request);
|
||||||
|
|
|
@ -59,7 +59,7 @@ class mtpRequestData : public mtpBuffer {
|
||||||
public:
|
public:
|
||||||
// in toSend: = 0 - must send in container, > 0 - can send without container
|
// in toSend: = 0 - must send in container, > 0 - can send without container
|
||||||
// in haveSent: = 0 - container with msgIds, > 0 - when was sent
|
// in haveSent: = 0 - container with msgIds, > 0 - when was sent
|
||||||
uint64 msDate;
|
TimeMs msDate;
|
||||||
|
|
||||||
mtpRequestId requestId;
|
mtpRequestId requestId;
|
||||||
mtpRequest after;
|
mtpRequest after;
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace {
|
||||||
RequestMap requestMap;
|
RequestMap requestMap;
|
||||||
QReadWriteLock requestMapLock;
|
QReadWriteLock requestMapLock;
|
||||||
|
|
||||||
typedef QPair<mtpRequestId, uint64> DelayedRequest;
|
typedef QPair<mtpRequestId, TimeMs> DelayedRequest;
|
||||||
typedef QList<DelayedRequest> DelayedRequestsList;
|
typedef QList<DelayedRequest> DelayedRequestsList;
|
||||||
DelayedRequestsList delayedRequests;
|
DelayedRequestsList delayedRequests;
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ namespace {
|
||||||
secs = m.captured(1).toInt();
|
secs = m.captured(1).toInt();
|
||||||
// if (secs >= 60) return false;
|
// if (secs >= 60) return false;
|
||||||
}
|
}
|
||||||
uint64 sendAt = getms(true) + secs * 1000 + 10;
|
auto sendAt = getms(true) + secs * 1000 + 10;
|
||||||
DelayedRequestsList::iterator i = delayedRequests.begin(), e = delayedRequests.end();
|
DelayedRequestsList::iterator i = delayedRequests.begin(), e = delayedRequests.end();
|
||||||
for (; i != e; ++i) {
|
for (; i != e; ++i) {
|
||||||
if (i->first == requestId) return true;
|
if (i->first == requestId) return true;
|
||||||
|
@ -340,7 +340,6 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint64 at = 0;
|
|
||||||
DelayedRequestsList::iterator i = delayedRequests.begin(), e = delayedRequests.end();
|
DelayedRequestsList::iterator i = delayedRequests.begin(), e = delayedRequests.end();
|
||||||
for (; i != e; ++i) {
|
for (; i != e; ++i) {
|
||||||
if (i->first == requestId) return true;
|
if (i->first == requestId) return true;
|
||||||
|
@ -587,7 +586,7 @@ GlobalSlotCarrier::GlobalSlotCarrier() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalSlotCarrier::checkDelayed() {
|
void GlobalSlotCarrier::checkDelayed() {
|
||||||
uint64 now = getms(true);
|
auto now = getms(true);
|
||||||
while (!delayedRequests.isEmpty() && now >= delayedRequests.front().second) {
|
while (!delayedRequests.isEmpty() && now >= delayedRequests.front().second) {
|
||||||
mtpRequestId requestId = delayedRequests.front().first;
|
mtpRequestId requestId = delayedRequests.front().first;
|
||||||
delayedRequests.pop_front();
|
delayedRequests.pop_front();
|
||||||
|
|
|
@ -150,18 +150,18 @@ int32 dcstate(int32 dc = 0);
|
||||||
QString dctransport(int32 dc = 0);
|
QString dctransport(int32 dc = 0);
|
||||||
|
|
||||||
template <typename TRequest>
|
template <typename TRequest>
|
||||||
inline mtpRequestId send(const TRequest &request, RPCResponseHandler callbacks = RPCResponseHandler(), int32 dc = 0, uint64 msCanWait = 0, mtpRequestId after = 0) {
|
inline mtpRequestId send(const TRequest &request, RPCResponseHandler callbacks = RPCResponseHandler(), int32 dc = 0, TimeMs msCanWait = 0, mtpRequestId after = 0) {
|
||||||
if (internal::Session *session = internal::getSession(dc)) {
|
if (internal::Session *session = internal::getSession(dc)) {
|
||||||
return session->send(request, callbacks, msCanWait, true, !dc, after);
|
return session->send(request, callbacks, msCanWait, true, !dc, after);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
template <typename TRequest>
|
template <typename TRequest>
|
||||||
inline mtpRequestId send(const TRequest &request, RPCDoneHandlerPtr onDone, RPCFailHandlerPtr onFail = RPCFailHandlerPtr(), int32 dc = 0, uint64 msCanWait = 0, mtpRequestId after = 0) {
|
inline mtpRequestId send(const TRequest &request, RPCDoneHandlerPtr onDone, RPCFailHandlerPtr onFail = RPCFailHandlerPtr(), int32 dc = 0, TimeMs msCanWait = 0, mtpRequestId after = 0) {
|
||||||
return send(request, RPCResponseHandler(onDone, onFail), dc, msCanWait, after);
|
return send(request, RPCResponseHandler(onDone, onFail), dc, msCanWait, after);
|
||||||
}
|
}
|
||||||
inline void sendAnything(int32 dc = 0, uint64 msCanWait = 0) {
|
inline void sendAnything(int32 dc = 0, TimeMs msCanWait = 0) {
|
||||||
if (internal::Session *session = internal::getSession(dc)) {
|
if (auto session = internal::getSession(dc)) {
|
||||||
return session->sendAnything(msCanWait);
|
return session->sendAnything(msCanWait);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ typedef QMap<int, DcOption> DcOptions;
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <typename TRequest>
|
template <typename TRequest>
|
||||||
mtpRequestId Session::send(const TRequest &request, RPCResponseHandler callbacks, uint64 msCanWait, bool needsLayer, bool toMainDC, mtpRequestId after) {
|
mtpRequestId Session::send(const TRequest &request, RPCResponseHandler callbacks, TimeMs msCanWait, bool needsLayer, bool toMainDC, mtpRequestId after) {
|
||||||
mtpRequestId requestId = 0;
|
mtpRequestId requestId = 0;
|
||||||
try {
|
try {
|
||||||
uint32 requestSize = request.innerLength() >> 2;
|
uint32 requestSize = request.innerLength() >> 2;
|
||||||
|
|
|
@ -165,12 +165,12 @@ void Session::unpaused() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::sendAnything(quint64 msCanWait) {
|
void Session::sendAnything(qint64 msCanWait) {
|
||||||
if (_killed) {
|
if (_killed) {
|
||||||
DEBUG_LOG(("Session Error: can't send anything in a killed session"));
|
DEBUG_LOG(("Session Error: can't send anything in a killed session"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint64 ms = getms(true);
|
auto ms = getms(true);
|
||||||
if (msSendCall) {
|
if (msSendCall) {
|
||||||
if (ms > msSendCall + msWait) {
|
if (ms > msSendCall + msWait) {
|
||||||
msWait = 0;
|
msWait = 0;
|
||||||
|
@ -246,7 +246,7 @@ void Session::checkRequestsByTimer() {
|
||||||
QReadLocker locker(data.haveSentMutex());
|
QReadLocker locker(data.haveSentMutex());
|
||||||
mtpRequestMap &haveSent(data.haveSentMap());
|
mtpRequestMap &haveSent(data.haveSentMap());
|
||||||
uint32 haveSentCount(haveSent.size());
|
uint32 haveSentCount(haveSent.size());
|
||||||
uint64 ms = getms(true);
|
auto ms = getms(true);
|
||||||
for (mtpRequestMap::iterator i = haveSent.begin(), e = haveSent.end(); i != e; ++i) {
|
for (mtpRequestMap::iterator i = haveSent.begin(), e = haveSent.end(); i != e; ++i) {
|
||||||
mtpRequest &req(i.value());
|
mtpRequest &req(i.value());
|
||||||
if (req->msDate > 0) {
|
if (req->msDate > 0) {
|
||||||
|
@ -386,7 +386,7 @@ QString Session::transport() const {
|
||||||
return _connection ? _connection->transport() : QString();
|
return _connection ? _connection->transport() : QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
mtpRequestId Session::resend(quint64 msgId, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
|
mtpRequestId Session::resend(quint64 msgId, qint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
|
||||||
mtpRequest request;
|
mtpRequest request;
|
||||||
{
|
{
|
||||||
QWriteLocker locker(data.haveSentMutex());
|
QWriteLocker locker(data.haveSentMutex());
|
||||||
|
@ -426,7 +426,7 @@ mtpRequestId Session::resend(quint64 msgId, quint64 msCanWait, bool forceContain
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::resendMany(QVector<quint64> msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
|
void Session::resendMany(QVector<quint64> msgIds, qint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
|
||||||
for (int32 i = 0, l = msgIds.size(); i < l; ++i) {
|
for (int32 i = 0, l = msgIds.size(); i < l; ++i) {
|
||||||
resend(msgIds.at(i), msCanWait, forceContainer, sendMsgStateInfo);
|
resend(msgIds.at(i), msCanWait, forceContainer, sendMsgStateInfo);
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,7 @@ void Session::resendAll() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::sendPrepared(const mtpRequest &request, uint64 msCanWait, bool newRequest) { // returns true, if emit of needToSend() is needed
|
void Session::sendPrepared(const mtpRequest &request, TimeMs msCanWait, bool newRequest) { // returns true, if emit of needToSend() is needed
|
||||||
{
|
{
|
||||||
QWriteLocker locker(data.toSendMutex());
|
QWriteLocker locker(data.toSendMutex());
|
||||||
data.toSendMap().insert(request->requestId, request);
|
data.toSendMap().insert(request->requestId, request);
|
||||||
|
|
|
@ -243,7 +243,7 @@ public:
|
||||||
void notifyLayerInited(bool wasInited);
|
void notifyLayerInited(bool wasInited);
|
||||||
|
|
||||||
template <typename TRequest>
|
template <typename TRequest>
|
||||||
mtpRequestId send(const TRequest &request, RPCResponseHandler callbacks = RPCResponseHandler(), uint64 msCanWait = 0, bool needsLayer = false, bool toMainDC = false, mtpRequestId after = 0); // send mtp request
|
mtpRequestId send(const TRequest &request, RPCResponseHandler callbacks = RPCResponseHandler(), TimeMs msCanWait = 0, bool needsLayer = false, bool toMainDC = false, mtpRequestId after = 0); // send mtp request
|
||||||
|
|
||||||
void ping();
|
void ping();
|
||||||
void cancel(mtpRequestId requestId, mtpMsgId msgId);
|
void cancel(mtpRequestId requestId, mtpMsgId msgId);
|
||||||
|
@ -251,7 +251,7 @@ public:
|
||||||
int32 getState() const;
|
int32 getState() const;
|
||||||
QString transport() const;
|
QString transport() const;
|
||||||
|
|
||||||
void sendPrepared(const mtpRequest &request, uint64 msCanWait = 0, bool newRequest = true); // nulls msgId and seqNo in request, if newRequest = true
|
void sendPrepared(const mtpRequest &request, TimeMs msCanWait = 0, bool newRequest = true); // nulls msgId and seqNo in request, if newRequest = true
|
||||||
|
|
||||||
~Session();
|
~Session();
|
||||||
|
|
||||||
|
@ -264,8 +264,8 @@ signals:
|
||||||
public slots:
|
public slots:
|
||||||
void needToResumeAndSend();
|
void needToResumeAndSend();
|
||||||
|
|
||||||
mtpRequestId resend(quint64 msgId, quint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false);
|
mtpRequestId resend(quint64 msgId, qint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false);
|
||||||
void resendMany(QVector<quint64> msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo);
|
void resendMany(QVector<quint64> msgIds, qint64 msCanWait, bool forceContainer, bool sendMsgStateInfo);
|
||||||
void resendAll(); // after connection restart
|
void resendAll(); // after connection restart
|
||||||
|
|
||||||
void authKeyCreatedForDC();
|
void authKeyCreatedForDC();
|
||||||
|
@ -276,7 +276,7 @@ public slots:
|
||||||
void onConnectionStateChange(qint32 newState);
|
void onConnectionStateChange(qint32 newState);
|
||||||
void onResetDone();
|
void onResetDone();
|
||||||
|
|
||||||
void sendAnything(quint64 msCanWait = 0);
|
void sendAnything(qint64 msCanWait = 0);
|
||||||
void sendPong(quint64 msgId, quint64 pingId);
|
void sendPong(quint64 msgId, quint64 pingId);
|
||||||
void sendMsgsStateInfo(quint64 msgId, QByteArray data);
|
void sendMsgsStateInfo(quint64 msgId, QByteArray data);
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ private:
|
||||||
int32 dcWithShift;
|
int32 dcWithShift;
|
||||||
DcenterPtr dc;
|
DcenterPtr dc;
|
||||||
|
|
||||||
uint64 msSendCall, msWait;
|
TimeMs msSendCall, msWait;
|
||||||
|
|
||||||
bool _ping;
|
bool _ping;
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ void RadialProgressItem::step_iconOver(float64 ms, bool timer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialProgressItem::step_radial(uint64 ms, bool timer) {
|
void RadialProgressItem::step_radial(TimeMs ms, bool timer) {
|
||||||
if (timer) {
|
if (timer) {
|
||||||
Ui::repaintHistoryItem(_parent);
|
Ui::repaintHistoryItem(_parent);
|
||||||
} else {
|
} else {
|
||||||
|
@ -119,7 +119,7 @@ RadialProgressItem::~RadialProgressItem() {
|
||||||
delete base::take(_radial);
|
delete base::take(_radial);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusText::update(int newSize, int fullSize, int duration, int64 realDuration) {
|
void StatusText::update(int newSize, int fullSize, int duration, TimeMs realDuration) {
|
||||||
setSize(newSize);
|
setSize(newSize);
|
||||||
if (_size == FileStatusSizeReady) {
|
if (_size == FileStatusSizeReady) {
|
||||||
_text = (duration >= 0) ? formatDurationAndSizeText(duration, fullSize) : (duration < -1 ? formatGifAndSizeText(fullSize) : formatSizeText(fullSize));
|
_text = (duration >= 0) ? formatDurationAndSizeText(duration, fullSize) : (duration < -1 ? formatGifAndSizeText(fullSize) : formatSizeText(fullSize));
|
||||||
|
@ -163,7 +163,7 @@ public:
|
||||||
PhotoVideoCheckbox(UpdateCallback callback) : _updateCallback(callback), _check(st::overviewCheck, _updateCallback) {
|
PhotoVideoCheckbox(UpdateCallback callback) : _updateCallback(callback), _check(st::overviewCheck, _updateCallback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(Painter &p, uint64 ms, int width, int height, bool selected, bool selecting);
|
void paint(Painter &p, TimeMs ms, int width, int height, bool selected, bool selecting);
|
||||||
|
|
||||||
void setActive(bool active);
|
void setActive(bool active);
|
||||||
void setPressed(bool pressed);
|
void setPressed(bool pressed);
|
||||||
|
@ -180,7 +180,7 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void PhotoVideoCheckbox::paint(Painter &p, uint64 ms, int width, int height, bool selected, bool selecting) {
|
void PhotoVideoCheckbox::paint(Painter &p, TimeMs ms, int width, int height, bool selected, bool selecting) {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
p.fillRect(0, 0, width, height, st::overviewPhotoSelectOverlay);
|
p.fillRect(0, 0, width, height, st::overviewPhotoSelectOverlay);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace Layout {
|
||||||
|
|
||||||
class PaintContext : public PaintContextBase {
|
class PaintContext : public PaintContextBase {
|
||||||
public:
|
public:
|
||||||
PaintContext(uint64 ms, bool selecting) : PaintContextBase(ms, selecting), isAfterDate(false) {
|
PaintContext(TimeMs ms, bool selecting) : PaintContextBase(ms, selecting), isAfterDate(false) {
|
||||||
}
|
}
|
||||||
bool isAfterDate;
|
bool isAfterDate;
|
||||||
|
|
||||||
|
@ -112,12 +112,12 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
void step_iconOver(float64 ms, bool timer);
|
void step_iconOver(float64 ms, bool timer);
|
||||||
void step_radial(uint64 ms, bool timer);
|
void step_radial(TimeMs ms, bool timer);
|
||||||
|
|
||||||
void ensureRadial();
|
void ensureRadial();
|
||||||
void checkRadialFinished();
|
void checkRadialFinished();
|
||||||
|
|
||||||
bool isRadialAnimation(uint64 ms) const {
|
bool isRadialAnimation(TimeMs ms) const {
|
||||||
if (!_radial || !_radial->animating()) return false;
|
if (!_radial || !_radial->animating()) return false;
|
||||||
|
|
||||||
_radial->step(ms);
|
_radial->step(ms);
|
||||||
|
@ -140,7 +140,7 @@ protected:
|
||||||
class StatusText {
|
class StatusText {
|
||||||
public:
|
public:
|
||||||
// duration = -1 - no duration, duration = -2 - "GIF" duration
|
// duration = -1 - no duration, duration = -2 - "GIF" duration
|
||||||
void update(int newSize, int fullSize, int duration, int64 realDuration);
|
void update(int newSize, int fullSize, int duration, TimeMs realDuration);
|
||||||
void setSize(int newSize);
|
void setSize(int newSize);
|
||||||
|
|
||||||
int size() const {
|
int size() const {
|
||||||
|
|
|
@ -105,7 +105,7 @@ bool OverviewInner::event(QEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewInner::touchUpdateSpeed() {
|
void OverviewInner::touchUpdateSpeed() {
|
||||||
const uint64 nowTime = getms();
|
const auto nowTime = getms();
|
||||||
if (_touchPrevPosValid) {
|
if (_touchPrevPosValid) {
|
||||||
const int elapsed = nowTime - _touchSpeedTime;
|
const int elapsed = nowTime - _touchSpeedTime;
|
||||||
if (elapsed) {
|
if (elapsed) {
|
||||||
|
@ -781,7 +781,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
|
||||||
if (!trivial) {
|
if (!trivial) {
|
||||||
p.setClipRect(r);
|
p.setClipRect(r);
|
||||||
}
|
}
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
Overview::Layout::PaintContext context(ms, _selMode);
|
Overview::Layout::PaintContext context(ms, _selMode);
|
||||||
|
|
||||||
if (_history->overview[_type].isEmpty() && (!_migrated || !_history->overviewLoaded(_type) || _migrated->overview[_type].isEmpty())) {
|
if (_history->overview[_type].isEmpty() && (!_migrated || !_history->overviewLoaded(_type) || _migrated->overview[_type].isEmpty())) {
|
||||||
|
@ -1560,7 +1560,7 @@ void OverviewInner::onTouchSelect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewInner::onTouchScrollTimer() {
|
void OverviewInner::onTouchScrollTimer() {
|
||||||
uint64 nowTime = getms();
|
auto nowTime = getms();
|
||||||
if (_touchScrollState == Ui::TouchScrollState::Acceleration && _touchWaitingAcceleration && (nowTime - _touchAccelerationTime) > 40) {
|
if (_touchScrollState == Ui::TouchScrollState::Acceleration && _touchWaitingAcceleration && (nowTime - _touchAccelerationTime) > 40) {
|
||||||
_touchScrollState = Ui::TouchScrollState::Manual;
|
_touchScrollState = Ui::TouchScrollState::Manual;
|
||||||
touchResetSpeed();
|
touchResetSpeed();
|
||||||
|
|
|
@ -263,9 +263,9 @@ private:
|
||||||
bool _touchPrevPosValid = false;
|
bool _touchPrevPosValid = false;
|
||||||
bool _touchWaitingAcceleration = false;
|
bool _touchWaitingAcceleration = false;
|
||||||
QPoint _touchSpeed;
|
QPoint _touchSpeed;
|
||||||
uint64 _touchSpeedTime = 0;
|
TimeMs _touchSpeedTime = 0;
|
||||||
uint64 _touchAccelerationTime = 0;
|
TimeMs _touchAccelerationTime = 0;
|
||||||
uint64 _touchTime = 0;
|
TimeMs _touchTime = 0;
|
||||||
QTimer _touchScrollTimer;
|
QTimer _touchScrollTimer;
|
||||||
|
|
||||||
Ui::PopupMenu *_menu = nullptr;
|
Ui::PopupMenu *_menu = nullptr;
|
||||||
|
|
|
@ -81,7 +81,7 @@ private:
|
||||||
int _psCheckStatusIconLeft = 100;
|
int _psCheckStatusIconLeft = 100;
|
||||||
|
|
||||||
QTimer _psUpdateIndicatorTimer;
|
QTimer _psUpdateIndicatorTimer;
|
||||||
uint64 _psLastIndicatorUpdate = 0;
|
TimeMs _psLastIndicatorUpdate = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -576,7 +576,7 @@ void queryUserNotificationState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr int QuerySettingsEachMs = 1000;
|
static constexpr int QuerySettingsEachMs = 1000;
|
||||||
uint64 LastSettingsQueryMs = 0;
|
TimeMs LastSettingsQueryMs = 0;
|
||||||
|
|
||||||
void querySystemNotificationSettings() {
|
void querySystemNotificationSettings() {
|
||||||
auto ms = getms(true);
|
auto ms = getms(true);
|
||||||
|
|
|
@ -75,13 +75,13 @@ public:
|
||||||
_PsEventFilter *_psEventFilter = nullptr;
|
_PsEventFilter *_psEventFilter = nullptr;
|
||||||
|
|
||||||
QRect _monitorRect;
|
QRect _monitorRect;
|
||||||
uint64 _monitorLastGot = 0;
|
auto _monitorLastGot = 0LL;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
QRect psDesktopRect() {
|
QRect psDesktopRect() {
|
||||||
uint64 tnow = getms();
|
auto tnow = getms();
|
||||||
if (tnow > _monitorLastGot + 1000 || tnow < _monitorLastGot) {
|
if (tnow > _monitorLastGot + 1000LL || tnow < _monitorLastGot) {
|
||||||
_monitorLastGot = tnow;
|
_monitorLastGot = tnow;
|
||||||
_monitorRect = QApplication::desktop()->availableGeometry(App::wnd());
|
_monitorRect = QApplication::desktop()->availableGeometry(App::wnd());
|
||||||
}
|
}
|
||||||
|
@ -279,7 +279,7 @@ void psDeleteDir(const QString &dir) {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
uint64 _lastUserAction = 0;
|
auto _lastUserAction = 0LL;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ bool psIdleSupported() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 psIdleTime() {
|
TimeMs psIdleTime() {
|
||||||
return getms(true) - _lastUserAction;
|
return getms(true) - _lastUserAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ void psDeleteDir(const QString &dir);
|
||||||
|
|
||||||
void psUserActionDone();
|
void psUserActionDone();
|
||||||
bool psIdleSupported();
|
bool psIdleSupported();
|
||||||
uint64 psIdleTime();
|
TimeMs psIdleTime();
|
||||||
|
|
||||||
QStringList psInitLogs();
|
QStringList psInitLogs();
|
||||||
void psClearInitLogs();
|
void psClearInitLogs();
|
||||||
|
|
|
@ -49,12 +49,14 @@ namespace {
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
QRect _monitorRect;
|
|
||||||
uint64 _monitorLastGot = 0;
|
QRect _monitorRect;
|
||||||
}
|
TimeMs _monitorLastGot = 0;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
QRect psDesktopRect() {
|
QRect psDesktopRect() {
|
||||||
uint64 tnow = getms(true);
|
auto tnow = getms(true);
|
||||||
if (tnow > _monitorLastGot + 1000 || tnow < _monitorLastGot) {
|
if (tnow > _monitorLastGot + 1000 || tnow < _monitorLastGot) {
|
||||||
_monitorLastGot = tnow;
|
_monitorLastGot = tnow;
|
||||||
_monitorRect = QApplication::desktop()->availableGeometry(App::wnd());
|
_monitorRect = QApplication::desktop()->availableGeometry(App::wnd());
|
||||||
|
@ -286,8 +288,10 @@ void psDeleteDir(const QString &dir) {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
uint64 _lastUserAction = 0;
|
|
||||||
}
|
auto _lastUserAction = 0LL;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void psUserActionDone() {
|
void psUserActionDone() {
|
||||||
_lastUserAction = getms(true);
|
_lastUserAction = getms(true);
|
||||||
|
@ -297,8 +301,8 @@ bool psIdleSupported() {
|
||||||
return objc_idleSupported();
|
return objc_idleSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 psIdleTime() {
|
TimeMs psIdleTime() {
|
||||||
int64 idleTime = 0;
|
auto idleTime = 0LL;
|
||||||
return objc_idleTime(idleTime) ? idleTime : (getms(true) - _lastUserAction);
|
return objc_idleTime(idleTime) ? idleTime : (getms(true) - _lastUserAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ void psDeleteDir(const QString &dir);
|
||||||
|
|
||||||
void psUserActionDone();
|
void psUserActionDone();
|
||||||
bool psIdleSupported();
|
bool psIdleSupported();
|
||||||
uint64 psIdleTime();
|
TimeMs psIdleTime();
|
||||||
|
|
||||||
QStringList psInitLogs();
|
QStringList psInitLogs();
|
||||||
void psClearInitLogs();
|
void psClearInitLogs();
|
||||||
|
|
|
@ -29,7 +29,7 @@ void objc_activateWnd(WId winId);
|
||||||
void objc_debugShowAlert(const QString &str);
|
void objc_debugShowAlert(const QString &str);
|
||||||
void objc_outputDebugString(const QString &str);
|
void objc_outputDebugString(const QString &str);
|
||||||
bool objc_idleSupported();
|
bool objc_idleSupported();
|
||||||
bool objc_idleTime(int64 &idleTime);
|
bool objc_idleTime(TimeMs &idleTime);
|
||||||
|
|
||||||
bool objc_showOpenWithMenu(int x, int y, const QString &file);
|
bool objc_showOpenWithMenu(int x, int y, const QString &file);
|
||||||
|
|
||||||
|
|
|
@ -261,11 +261,11 @@ void objc_outputDebugString(const QString &str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool objc_idleSupported() {
|
bool objc_idleSupported() {
|
||||||
int64 idleTime = 0;
|
auto idleTime = 0LL;
|
||||||
return objc_idleTime(idleTime);
|
return objc_idleTime(idleTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool objc_idleTime(int64 &idleTime) { // taken from https://github.com/trueinteractions/tint/issues/53
|
bool objc_idleTime(TimeMs &idleTime) { // taken from https://github.com/trueinteractions/tint/issues/53
|
||||||
CFMutableDictionaryRef properties = 0;
|
CFMutableDictionaryRef properties = 0;
|
||||||
CFTypeRef obj;
|
CFTypeRef obj;
|
||||||
mach_port_t masterPort;
|
mach_port_t masterPort;
|
||||||
|
@ -314,7 +314,7 @@ bool objc_idleTime(int64 &idleTime) { // taken from https://github.com/trueinter
|
||||||
IOObjectRelease(iter);
|
IOObjectRelease(iter);
|
||||||
if (result == err) return false;
|
if (result == err) return false;
|
||||||
|
|
||||||
idleTime = int64(result);
|
idleTime = static_cast<TimeMs>(result);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,8 +156,10 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
uint64 _lastUserAction = 0;
|
|
||||||
}
|
TimeMs _lastUserAction = 0;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void psUserActionDone() {
|
void psUserActionDone() {
|
||||||
_lastUserAction = getms(true);
|
_lastUserAction = getms(true);
|
||||||
|
@ -170,7 +172,7 @@ bool psIdleSupported() {
|
||||||
return GetLastInputInfo(&lii);
|
return GetLastInputInfo(&lii);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 psIdleTime() {
|
TimeMs psIdleTime() {
|
||||||
LASTINPUTINFO lii;
|
LASTINPUTINFO lii;
|
||||||
lii.cbSize = sizeof(LASTINPUTINFO);
|
lii.cbSize = sizeof(LASTINPUTINFO);
|
||||||
return GetLastInputInfo(&lii) ? (GetTickCount() - lii.dwTime) : (getms(true) - _lastUserAction);
|
return GetLastInputInfo(&lii) ? (GetTickCount() - lii.dwTime) : (getms(true) - _lastUserAction);
|
||||||
|
@ -417,13 +419,15 @@ void psDoCleanup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
QRect _monitorRect;
|
QRect _monitorRect;
|
||||||
uint64 _monitorLastGot = 0;
|
TimeMs _monitorLastGot = 0;
|
||||||
}
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
QRect psDesktopRect() {
|
QRect psDesktopRect() {
|
||||||
uint64 tnow = getms();
|
auto tnow = getms();
|
||||||
if (tnow > _monitorLastGot + 1000 || tnow < _monitorLastGot) {
|
if (tnow > _monitorLastGot + 1000LL || tnow < _monitorLastGot) {
|
||||||
_monitorLastGot = tnow;
|
_monitorLastGot = tnow;
|
||||||
HMONITOR hMonitor = MonitorFromWindow(App::wnd()->psHwnd(), MONITOR_DEFAULTTONEAREST);
|
HMONITOR hMonitor = MonitorFromWindow(App::wnd()->psHwnd(), MONITOR_DEFAULTTONEAREST);
|
||||||
if (hMonitor) {
|
if (hMonitor) {
|
||||||
|
|
|
@ -36,7 +36,7 @@ void psDeleteDir(const QString &dir);
|
||||||
|
|
||||||
void psUserActionDone();
|
void psUserActionDone();
|
||||||
bool psIdleSupported();
|
bool psIdleSupported();
|
||||||
uint64 psIdleTime();
|
TimeMs psIdleTime();
|
||||||
|
|
||||||
QStringList psInitLogs();
|
QStringList psInitLogs();
|
||||||
void psClearInitLogs();
|
void psClearInitLogs();
|
||||||
|
|
|
@ -85,7 +85,7 @@ RecentStickerPreload gRecentStickersPreload;
|
||||||
RecentStickerPack gRecentStickers;
|
RecentStickerPack gRecentStickers;
|
||||||
|
|
||||||
SavedGifs gSavedGifs;
|
SavedGifs gSavedGifs;
|
||||||
uint64 gLastSavedGifsUpdate = 0;
|
TimeMs gLastSavedGifsUpdate = 0;
|
||||||
bool gShowingSavedGifs = false;
|
bool gShowingSavedGifs = false;
|
||||||
|
|
||||||
RecentHashtagPack gRecentWriteHashtags, gRecentSearchHashtags;
|
RecentHashtagPack gRecentWriteHashtags, gRecentSearchHashtags;
|
||||||
|
@ -94,7 +94,7 @@ RecentInlineBots gRecentInlineBots;
|
||||||
|
|
||||||
bool gPasswordRecovered = false;
|
bool gPasswordRecovered = false;
|
||||||
int32 gPasscodeBadTries = 0;
|
int32 gPasscodeBadTries = 0;
|
||||||
uint64 gPasscodeLastTry = 0;
|
TimeMs gPasscodeLastTry = 0;
|
||||||
|
|
||||||
int32 gLang = -2; // auto
|
int32 gLang = -2; // auto
|
||||||
QString gLangFile;
|
QString gLangFile;
|
||||||
|
|
|
@ -183,7 +183,7 @@ typedef QMap<EmojiPtr, StickerPack> StickersByEmojiMap;
|
||||||
|
|
||||||
typedef QVector<DocumentData*> SavedGifs;
|
typedef QVector<DocumentData*> SavedGifs;
|
||||||
DeclareRefSetting(SavedGifs, SavedGifs);
|
DeclareRefSetting(SavedGifs, SavedGifs);
|
||||||
DeclareSetting(uint64, LastSavedGifsUpdate);
|
DeclareSetting(TimeMs, LastSavedGifsUpdate);
|
||||||
DeclareSetting(bool, ShowingSavedGifs);
|
DeclareSetting(bool, ShowingSavedGifs);
|
||||||
|
|
||||||
typedef QList<QPair<QString, ushort> > RecentHashtagPack;
|
typedef QList<QPair<QString, ushort> > RecentHashtagPack;
|
||||||
|
@ -197,11 +197,11 @@ DeclareRefSetting(RecentInlineBots, RecentInlineBots);
|
||||||
DeclareSetting(bool, PasswordRecovered);
|
DeclareSetting(bool, PasswordRecovered);
|
||||||
|
|
||||||
DeclareSetting(int32, PasscodeBadTries);
|
DeclareSetting(int32, PasscodeBadTries);
|
||||||
DeclareSetting(uint64, PasscodeLastTry);
|
DeclareSetting(TimeMs, PasscodeLastTry);
|
||||||
|
|
||||||
inline bool passcodeCanTry() {
|
inline bool passcodeCanTry() {
|
||||||
if (cPasscodeBadTries() < 3) return true;
|
if (cPasscodeBadTries() < 3) return true;
|
||||||
uint64 dt = getms(true) - cPasscodeLastTry();
|
auto dt = getms(true) - cPasscodeLastTry();
|
||||||
switch (cPasscodeBadTries()) {
|
switch (cPasscodeBadTries()) {
|
||||||
case 3: return dt >= 5000;
|
case 3: return dt >= 5000;
|
||||||
case 4: return dt >= 10000;
|
case 4: return dt >= 10000;
|
||||||
|
|
|
@ -127,11 +127,11 @@ void BackgroundRow::radialStart() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 BackgroundRow::radialTimeShift() const {
|
TimeMs BackgroundRow::radialTimeShift() const {
|
||||||
return st::radialDuration;
|
return st::radialDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundRow::step_radial(uint64 ms, bool timer) {
|
void BackgroundRow::step_radial(TimeMs ms, bool timer) {
|
||||||
_radial.update(radialProgress(), !radialLoading(), ms + radialTimeShift());
|
_radial.update(radialProgress(), !radialLoading(), ms + radialTimeShift());
|
||||||
if (timer && _radial.animating()) {
|
if (timer && _radial.animating()) {
|
||||||
rtlupdate(radialRect());
|
rtlupdate(radialRect());
|
||||||
|
|
|
@ -48,8 +48,8 @@ private:
|
||||||
bool radialLoading() const;
|
bool radialLoading() const;
|
||||||
QRect radialRect() const;
|
QRect radialRect() const;
|
||||||
void radialStart();
|
void radialStart();
|
||||||
uint64 radialTimeShift() const;
|
TimeMs radialTimeShift() const;
|
||||||
void step_radial(uint64 ms, bool timer);
|
void step_radial(TimeMs ms, bool timer);
|
||||||
|
|
||||||
QPixmap _background;
|
QPixmap _background;
|
||||||
ChildWidget<Ui::LinkButton> _chooseFromGallery;
|
ChildWidget<Ui::LinkButton> _chooseFromGallery;
|
||||||
|
|
|
@ -1779,7 +1779,7 @@ void StickerPanInner::notify_inlineItemLayoutChanged(const InlineItem *layout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::ui_repaintInlineItem(const InlineItem *layout) {
|
void StickerPanInner::ui_repaintInlineItem(const InlineItem *layout) {
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
if (_lastScrolled + 100 <= ms) {
|
if (_lastScrolled + 100 <= ms) {
|
||||||
update();
|
update();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2186,7 +2186,7 @@ void StickerPanInner::onPreview() {
|
||||||
void StickerPanInner::onUpdateInlineItems() {
|
void StickerPanInner::onUpdateInlineItems() {
|
||||||
if (!showingInlineItems()) return;
|
if (!showingInlineItems()) return;
|
||||||
|
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
if (_lastScrolled + 100 <= ms) {
|
if (_lastScrolled + 100 <= ms) {
|
||||||
update();
|
update();
|
||||||
} else {
|
} else {
|
||||||
|
@ -3198,7 +3198,7 @@ void EmojiPan::updateIcons() {
|
||||||
update(r.left(), _iconsTop, r.width(), st::emojiCategory.height);
|
update(r.left(), _iconsTop, r.width(), st::emojiCategory.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPan::step_icons(uint64 ms, bool timer) {
|
void EmojiPan::step_icons(TimeMs ms, bool timer) {
|
||||||
if (_emojiShown) {
|
if (_emojiShown) {
|
||||||
_a_icons.stop();
|
_a_icons.stop();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -364,7 +364,7 @@ private:
|
||||||
bool _setGifCommand = false;
|
bool _setGifCommand = false;
|
||||||
UserData *_inlineBot;
|
UserData *_inlineBot;
|
||||||
QString _inlineBotTitle;
|
QString _inlineBotTitle;
|
||||||
uint64 _lastScrolled = 0;
|
TimeMs _lastScrolled = 0;
|
||||||
QTimer _updateInlineItems;
|
QTimer _updateInlineItems;
|
||||||
bool _inlineWithThumb = false;
|
bool _inlineWithThumb = false;
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ public:
|
||||||
return _hiding || _hideTimer.isActive();
|
return _hiding || _hideTimer.isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
void step_icons(uint64 ms, bool timer);
|
void step_icons(TimeMs ms, bool timer);
|
||||||
|
|
||||||
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
||||||
|
|
||||||
|
@ -663,7 +663,7 @@ private:
|
||||||
int _iconsMax = 0;
|
int _iconsMax = 0;
|
||||||
anim::ivalue _iconsX = { 0, 0 };
|
anim::ivalue _iconsX = { 0, 0 };
|
||||||
anim::ivalue _iconSelX = { 0, 0 };
|
anim::ivalue _iconSelX = { 0, 0 };
|
||||||
uint64 _iconsStartAnim = 0;
|
TimeMs _iconsStartAnim = 0;
|
||||||
|
|
||||||
bool _emojiShown = true;
|
bool _emojiShown = true;
|
||||||
bool _shownFromInlineQuery = false;
|
bool _shownFromInlineQuery = false;
|
||||||
|
|
|
@ -810,7 +810,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PtsWaiter _ptsWaiter;
|
PtsWaiter _ptsWaiter;
|
||||||
uint64 _lastFullUpdate = 0;
|
TimeMs _lastFullUpdate = 0;
|
||||||
|
|
||||||
int _membersCount = 1;
|
int _membersCount = 1;
|
||||||
int _adminsCount = 1;
|
int _adminsCount = 1;
|
||||||
|
@ -1410,3 +1410,23 @@ struct MessageCursor {
|
||||||
inline bool operator==(const MessageCursor &a, const MessageCursor &b) {
|
inline bool operator==(const MessageCursor &a, const MessageCursor &b) {
|
||||||
return (a.position == b.position) && (a.anchor == b.anchor) && (a.scroll == b.scroll);
|
return (a.position == b.position) && (a.anchor == b.anchor) && (a.scroll == b.scroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SendAction {
|
||||||
|
enum class Type {
|
||||||
|
Typing,
|
||||||
|
RecordVideo,
|
||||||
|
UploadVideo,
|
||||||
|
RecordVoice,
|
||||||
|
UploadVoice,
|
||||||
|
UploadPhoto,
|
||||||
|
UploadFile,
|
||||||
|
ChooseLocation,
|
||||||
|
ChooseContact,
|
||||||
|
PlayGame,
|
||||||
|
};
|
||||||
|
SendAction(Type type, TimeMs until, int progress = 0) : type(type), until(until), progress(progress) {
|
||||||
|
}
|
||||||
|
Type type;
|
||||||
|
TimeMs until;
|
||||||
|
int progress;
|
||||||
|
};
|
||||||
|
|
|
@ -165,7 +165,7 @@ void AnimationManager::stop(Animation *obj) {
|
||||||
|
|
||||||
void AnimationManager::timeout() {
|
void AnimationManager::timeout() {
|
||||||
_iterating = true;
|
_iterating = true;
|
||||||
uint64 ms = getms();
|
auto ms = getms();
|
||||||
for_const (auto object, _objects) {
|
for_const (auto object, _objects) {
|
||||||
if (!_stopping.contains(object)) {
|
if (!_stopping.contains(object)) {
|
||||||
object->step(ms, true);
|
object->step(ms, true);
|
||||||
|
|
|
@ -438,7 +438,7 @@ class Animation;
|
||||||
class AnimationImplementation {
|
class AnimationImplementation {
|
||||||
public:
|
public:
|
||||||
virtual void start() {}
|
virtual void start() {}
|
||||||
virtual void step(Animation *a, uint64 ms, bool timer) = 0;
|
virtual void step(Animation *a, TimeMs ms, bool timer) = 0;
|
||||||
virtual ~AnimationImplementation() {}
|
virtual ~AnimationImplementation() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -457,7 +457,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() { _implementation->start(); }
|
void start() { _implementation->start(); }
|
||||||
void step(Animation *a, uint64 ms, bool timer) { _implementation->step(a, ms, timer); }
|
void step(Animation *a, TimeMs ms, bool timer) { _implementation->step(a, ms, timer); }
|
||||||
~AnimationCallbacks() { delete base::take(_implementation); }
|
~AnimationCallbacks() { delete base::take(_implementation); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -475,7 +475,7 @@ public:
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void step(uint64 ms, bool timer = false) {
|
void step(TimeMs ms, bool timer = false) {
|
||||||
_callbacks.step(this, ms, timer);
|
_callbacks.step(this, ms, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +509,7 @@ public:
|
||||||
_started = float64(getms());
|
_started = float64(getms());
|
||||||
}
|
}
|
||||||
|
|
||||||
void step(Animation *a, uint64 ms, bool timer) {
|
void step(Animation *a, TimeMs ms, bool timer) {
|
||||||
(_obj->*_method)(ms - _started, timer);
|
(_obj->*_method)(ms - _started, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,12 +527,12 @@ AnimationCallbacks animation(Type *obj, typename AnimationCallbacksRelative<Type
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
class AnimationCallbacksAbsolute : public AnimationImplementation {
|
class AnimationCallbacksAbsolute : public AnimationImplementation {
|
||||||
public:
|
public:
|
||||||
typedef void (Type::*Method)(uint64, bool);
|
typedef void (Type::*Method)(TimeMs, bool);
|
||||||
|
|
||||||
AnimationCallbacksAbsolute(Type *obj, Method method) : _obj(obj), _method(method) {
|
AnimationCallbacksAbsolute(Type *obj, Method method) : _obj(obj), _method(method) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void step(Animation *a, uint64 ms, bool timer) {
|
void step(Animation *a, TimeMs ms, bool timer) {
|
||||||
(_obj->*_method)(ms, timer);
|
(_obj->*_method)(ms, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,7 +558,7 @@ public:
|
||||||
_started = float64(getms());
|
_started = float64(getms());
|
||||||
}
|
}
|
||||||
|
|
||||||
void step(Animation *a, uint64 ms, bool timer) {
|
void step(Animation *a, TimeMs ms, bool timer) {
|
||||||
(_obj->*_method)(_param, ms - _started, timer);
|
(_obj->*_method)(_param, ms - _started, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,12 +577,12 @@ AnimationCallbacks animation(Param param, Type *obj, typename AnimationCallbacks
|
||||||
template <typename Type, typename Param>
|
template <typename Type, typename Param>
|
||||||
class AnimationCallbacksAbsoluteWithParam : public AnimationImplementation {
|
class AnimationCallbacksAbsoluteWithParam : public AnimationImplementation {
|
||||||
public:
|
public:
|
||||||
typedef void (Type::*Method)(Param, uint64, bool);
|
typedef void (Type::*Method)(Param, TimeMs, bool);
|
||||||
|
|
||||||
AnimationCallbacksAbsoluteWithParam(Param param, Type *obj, Method method) : _param(param), _obj(obj), _method(method) {
|
AnimationCallbacksAbsoluteWithParam(Param param, Type *obj, Method method) : _param(param), _obj(obj), _method(method) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void step(Animation *a, uint64 ms, bool timer) {
|
void step(Animation *a, TimeMs ms, bool timer) {
|
||||||
(_obj->*_method)(_param, ms, timer);
|
(_obj->*_method)(_param, ms, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,7 +603,7 @@ public:
|
||||||
using ValueType = typename AnimType::ValueType;
|
using ValueType = typename AnimType::ValueType;
|
||||||
using Callback = base::lambda<void()>;
|
using Callback = base::lambda<void()>;
|
||||||
|
|
||||||
void step(uint64 ms) {
|
void step(TimeMs ms) {
|
||||||
if (_data) {
|
if (_data) {
|
||||||
_data->a_animation.step(ms);
|
_data->a_animation.step(ms);
|
||||||
if (_data && !_data->a_animation.animating()) {
|
if (_data && !_data->a_animation.animating()) {
|
||||||
|
@ -621,7 +621,7 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool animating(uint64 ms) {
|
bool animating(TimeMs ms) {
|
||||||
step(ms);
|
step(ms);
|
||||||
return animating();
|
return animating();
|
||||||
}
|
}
|
||||||
|
@ -633,7 +633,7 @@ public:
|
||||||
ValueType current(const ValueType &def) const {
|
ValueType current(const ValueType &def) const {
|
||||||
return _data ? current() : def;
|
return _data ? current() : def;
|
||||||
}
|
}
|
||||||
ValueType current(uint64 ms, const ValueType &def) {
|
ValueType current(TimeMs ms, const ValueType &def) {
|
||||||
return animating(ms) ? current() : def;
|
return animating(ms) ? current() : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,8 +149,8 @@ void EmojiButton::paintEvent(QPaintEvent *e) {
|
||||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||||
QRect inner(QPoint((width() - st::historyEmojiCircle.width()) / 2, st::historyEmojiCircleTop), st::historyEmojiCircle);
|
QRect inner(QPoint((width() - st::historyEmojiCircle.width()) / 2, st::historyEmojiCircleTop), st::historyEmojiCircle);
|
||||||
if (loading > 0) {
|
if (loading > 0) {
|
||||||
int32 full = 5760;
|
int32 full = FullArcLength;
|
||||||
int32 start = qRound(full * float64(ms % uint64(st::historyEmojiCirclePeriod)) / st::historyEmojiCirclePeriod), part = qRound(loading * full / st::historyEmojiCirclePart);
|
int32 start = qRound(full * float64(ms % st::historyEmojiCirclePeriod) / st::historyEmojiCirclePeriod), part = qRound(loading * full / st::historyEmojiCirclePart);
|
||||||
p.drawArc(inner, start, full - part);
|
p.drawArc(inner, start, full - part);
|
||||||
} else {
|
} else {
|
||||||
p.drawEllipse(inner);
|
p.drawEllipse(inner);
|
||||||
|
|
|
@ -81,7 +81,7 @@ private:
|
||||||
FloatAnimation a_loading;
|
FloatAnimation a_loading;
|
||||||
Animation _a_loading;
|
Animation _a_loading;
|
||||||
|
|
||||||
void step_loading(uint64 ms, bool timer) {
|
void step_loading(TimeMs ms, bool timer) {
|
||||||
if (timer) {
|
if (timer) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ void RadialAnimation::start(float64 prg) {
|
||||||
_animation.start();
|
_animation.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialAnimation::update(float64 prg, bool finished, uint64 ms) {
|
void RadialAnimation::update(float64 prg, bool finished, TimeMs ms) {
|
||||||
int32 iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength);
|
int32 iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength);
|
||||||
if (iprg != a_arcEnd.to()) {
|
if (iprg != a_arcEnd.to()) {
|
||||||
a_arcEnd.start(iprg);
|
a_arcEnd.start(iprg);
|
||||||
|
@ -66,7 +66,7 @@ void RadialAnimation::stop() {
|
||||||
_animation.stop();
|
_animation.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialAnimation::step(uint64 ms) {
|
void RadialAnimation::step(TimeMs ms) {
|
||||||
_animation.step(ms);
|
_animation.step(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(float64 prg);
|
void start(float64 prg);
|
||||||
void update(float64 prg, bool finished, uint64 ms);
|
void update(float64 prg, bool finished, TimeMs ms);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void step(uint64 ms);
|
void step(TimeMs ms);
|
||||||
void step() {
|
void step() {
|
||||||
step(getms());
|
step(getms());
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,9 @@ public:
|
||||||
void draw(Painter &p, const QRect &inner, int32 thickness, const style::color &color);
|
void draw(Painter &p, const QRect &inner, int32 thickness, const style::color &color);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64 _firstStart = 0;
|
TimeMs _firstStart = 0;
|
||||||
uint64 _lastStart = 0;
|
TimeMs _lastStart = 0;
|
||||||
uint64 _lastTime = 0;
|
TimeMs _lastTime = 0;
|
||||||
float64 _opacity = 0.;
|
float64 _opacity = 0.;
|
||||||
anim::ivalue a_arcEnd, a_arcStart;
|
anim::ivalue a_arcEnd, a_arcStart;
|
||||||
Animation _animation;
|
Animation _animation;
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
Ripple(const style::RippleAnimation &st, QPoint origin, int startRadius, const QPixmap &mask, const UpdateCallback &update);
|
Ripple(const style::RippleAnimation &st, QPoint origin, int startRadius, const QPixmap &mask, const UpdateCallback &update);
|
||||||
Ripple(const style::RippleAnimation &st, const QPixmap &mask, const UpdateCallback &update);
|
Ripple(const style::RippleAnimation &st, const QPixmap &mask, const UpdateCallback &update);
|
||||||
|
|
||||||
void paint(QPainter &p, const QPixmap &mask, uint64 ms);
|
void paint(QPainter &p, const QPixmap &mask, TimeMs ms);
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
void unstop();
|
void unstop();
|
||||||
|
@ -86,7 +86,7 @@ RippleAnimation::Ripple::Ripple(const style::RippleAnimation &st, const QPixmap
|
||||||
_hide.start(UpdateCallback(_update), 0., 1., _st.hideDuration);
|
_hide.start(UpdateCallback(_update), 0., 1., _st.hideDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RippleAnimation::Ripple::paint(QPainter &p, const QPixmap &mask, uint64 ms) {
|
void RippleAnimation::Ripple::paint(QPainter &p, const QPixmap &mask, TimeMs ms) {
|
||||||
auto opacity = _hide.current(ms, _hiding ? 0. : 1.);
|
auto opacity = _hide.current(ms, _hiding ? 0. : 1.);
|
||||||
if (opacity == 0.) {
|
if (opacity == 0.) {
|
||||||
return;
|
return;
|
||||||
|
@ -176,7 +176,7 @@ void RippleAnimation::lastFinish() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RippleAnimation::paint(QPainter &p, int x, int y, int outerWidth, uint64 ms) {
|
void RippleAnimation::paint(QPainter &p, int x, int y, int outerWidth, TimeMs ms) {
|
||||||
if (_ripples.isEmpty()) {
|
if (_ripples.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue