mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 18:21:42 -05:00
Message edit warning timer (up to 15 minutes).
Displaying "edited" info in messages.
This commit is contained in:
parent
b28e9a6167
commit
0b2401132e
5 changed files with 75 additions and 20 deletions
|
@ -599,7 +599,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_forwarded_channel_via" = "Forwarded from {channel} via {inline_bot}";
|
"lng_forwarded_channel_via" = "Forwarded from {channel} via {inline_bot}";
|
||||||
"lng_forwarded_signed" = "{channel} ({user})";
|
"lng_forwarded_signed" = "{channel} ({user})";
|
||||||
"lng_in_reply_to" = "In reply to";
|
"lng_in_reply_to" = "In reply to";
|
||||||
"lng_edited" = "Edited";
|
"lng_edited" = "edited";
|
||||||
"lng_edited_date" = "Edited: {date}";
|
"lng_edited_date" = "Edited: {date}";
|
||||||
"lng_cancel_edit_post_sure" = "Cancel editing?";
|
"lng_cancel_edit_post_sure" = "Cancel editing?";
|
||||||
"lng_cancel_edit_post_yes" = "Yes";
|
"lng_cancel_edit_post_yes" = "Yes";
|
||||||
|
|
|
@ -1395,8 +1395,8 @@ void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
|
||||||
_sel = *i;
|
_sel = *i;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto i = shownDialogs()->cfind(_sel), b = shownDialogs()->cbegin(); i != b && (toSkip--); --i) {
|
for (auto i = shownDialogs()->cfind(_sel), b = shownDialogs()->cbegin(); i != b && (toSkip--);) {
|
||||||
_sel = *i;
|
_sel = *(--i);
|
||||||
}
|
}
|
||||||
if (toSkip && importantDialogs) {
|
if (toSkip && importantDialogs) {
|
||||||
_importantSwitchSel = true;
|
_importantSwitchSel = true;
|
||||||
|
|
|
@ -3095,8 +3095,7 @@ void HistoryItem::setId(MsgId newId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryItem::canEdit(const QDateTime &cur) const {
|
bool HistoryItem::canEdit(const QDateTime &cur) const {
|
||||||
auto channel = _history->peer->asChannel();
|
if (id < 0 || date.secsTo(cur) >= Global::EditTimeLimit()) return false;
|
||||||
if (!channel || id < 0 || date.secsTo(cur) >= Global::EditTimeLimit()) return false;
|
|
||||||
|
|
||||||
if (auto msg = toHistoryMessage()) {
|
if (auto msg = toHistoryMessage()) {
|
||||||
if (msg->Has<HistoryMessageVia>() || msg->Has<HistoryMessageForwarded>()) return false;
|
if (msg->Has<HistoryMessageVia>() || msg->Has<HistoryMessageForwarded>()) return false;
|
||||||
|
@ -3114,6 +3113,7 @@ bool HistoryItem::canEdit(const QDateTime &cur) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isPost()) {
|
if (isPost()) {
|
||||||
|
auto channel = _history->peer->asChannel();
|
||||||
return (channel->amCreator() || (channel->amEditor() && out()));
|
return (channel->amCreator() || (channel->amEditor() && out()));
|
||||||
}
|
}
|
||||||
return out();
|
return out();
|
||||||
|
@ -6484,7 +6484,7 @@ void HistoryMessageEdited::create(const QDateTime &editDate, const QDateTime &da
|
||||||
_editDate = editDate;
|
_editDate = editDate;
|
||||||
|
|
||||||
QString time = date.toString(cTimeFormat());
|
QString time = date.toString(cTimeFormat());
|
||||||
_edited.setText(st::msgDateFont, time, _textNameOptions);
|
_edited.setText(st::msgDateFont, lang(lng_edited) + ' ' + time, _textNameOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
int HistoryMessageEdited::maxWidth() const {
|
int HistoryMessageEdited::maxWidth() const {
|
||||||
|
|
|
@ -2070,9 +2070,9 @@ QString HistoryInner::tooltipText() const {
|
||||||
if (_dragCursorState == HistoryInDateCursorState && _dragAction == NoDrag) {
|
if (_dragCursorState == HistoryInDateCursorState && _dragAction == NoDrag) {
|
||||||
if (App::hoveredItem()) {
|
if (App::hoveredItem()) {
|
||||||
QString dateText = App::hoveredItem()->date.toString(QLocale::system().dateTimeFormat(QLocale::LongFormat));
|
QString dateText = App::hoveredItem()->date.toString(QLocale::system().dateTimeFormat(QLocale::LongFormat));
|
||||||
//if (auto edited = App::hoveredItem()->Get<HistoryMessageEdited>()) {
|
if (auto edited = App::hoveredItem()->Get<HistoryMessageEdited>()) {
|
||||||
// dateText += '\n' + lng_edited_date(lt_date, edited->_editDate.toString(QLocale::system().dateTimeFormat(QLocale::LongFormat)));
|
dateText += '\n' + lng_edited_date(lt_date, edited->_editDate.toString(QLocale::system().dateTimeFormat(QLocale::LongFormat)));
|
||||||
//}
|
}
|
||||||
return dateText;
|
return dateText;
|
||||||
}
|
}
|
||||||
} else if (_dragCursorState == HistoryInForwardedCursorState && _dragAction == NoDrag) {
|
} else if (_dragCursorState == HistoryInForwardedCursorState && _dragAction == NoDrag) {
|
||||||
|
@ -2985,6 +2985,8 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||||
|
|
||||||
connect(&_attachDragDocument, SIGNAL(dropped(const QMimeData*)), this, SLOT(onDocumentDrop(const QMimeData*)));
|
connect(&_attachDragDocument, SIGNAL(dropped(const QMimeData*)), this, SLOT(onDocumentDrop(const QMimeData*)));
|
||||||
connect(&_attachDragPhoto, SIGNAL(dropped(const QMimeData*)), this, SLOT(onPhotoDrop(const QMimeData*)));
|
connect(&_attachDragPhoto, SIGNAL(dropped(const QMimeData*)), this, SLOT(onPhotoDrop(const QMimeData*)));
|
||||||
|
|
||||||
|
connect(&_updateEditTimeLeftDisplay, SIGNAL(timeout()), this, SLOT(updateField()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::start() {
|
void HistoryWidget::start() {
|
||||||
|
@ -7077,9 +7079,10 @@ void HistoryWidget::keyPressEvent(QKeyEvent *e) {
|
||||||
if (_field.isEmpty() && !_editMsgId && !_replyToId) {
|
if (_field.isEmpty() && !_editMsgId && !_replyToId) {
|
||||||
App::contextItem(_history->lastSentMsg);
|
App::contextItem(_history->lastSentMsg);
|
||||||
onEditMessage();
|
onEditMessage();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// _scroll.keyPressEvent(e);
|
_scroll.keyPressEvent(e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
e->ignore();
|
e->ignore();
|
||||||
|
@ -7474,8 +7477,8 @@ void HistoryWidget::onEditMessage() {
|
||||||
_history->setEditDraft(std_::make_unique<HistoryEditDraft>(editData, to->id, cursor, false));
|
_history->setEditDraft(std_::make_unique<HistoryEditDraft>(editData, to->id, cursor, false));
|
||||||
applyDraft(false);
|
applyDraft(false);
|
||||||
|
|
||||||
_previewData = 0;
|
_previewData = nullptr;
|
||||||
if (HistoryMedia *media = to->getMedia()) {
|
if (auto media = to->getMedia()) {
|
||||||
if (media->type() == MediaTypeWebPage) {
|
if (media->type() == MediaTypeWebPage) {
|
||||||
_previewData = static_cast<HistoryWebPage*>(media)->webpage();
|
_previewData = static_cast<HistoryWebPage*>(media)->webpage();
|
||||||
updatePreview();
|
updatePreview();
|
||||||
|
@ -7491,7 +7494,7 @@ void HistoryWidget::onEditMessage() {
|
||||||
updateFieldPlaceholder();
|
updateFieldPlaceholder();
|
||||||
updateMouseTracking();
|
updateMouseTracking();
|
||||||
updateReplyToName();
|
updateReplyToName();
|
||||||
resizeEvent(0);
|
resizeEvent(nullptr);
|
||||||
updateField();
|
updateField();
|
||||||
|
|
||||||
_saveDraftText = true;
|
_saveDraftText = true;
|
||||||
|
@ -8089,7 +8092,7 @@ void HistoryWidget::updateField() {
|
||||||
update(0, fy, width(), height() - fy);
|
update(0, fy, width(), height() - fy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::drawField(Painter &p) {
|
void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||||
int32 backy = _field.y() - st::sendPadding, backh = _field.height() + 2 * st::sendPadding;
|
int32 backy = _field.y() - st::sendPadding, backh = _field.height() + 2 * st::sendPadding;
|
||||||
Text *from = 0, *text = 0;
|
Text *from = 0, *text = 0;
|
||||||
bool serviceColor = false, hasForward = readyToForward();
|
bool serviceColor = false, hasForward = readyToForward();
|
||||||
|
@ -8110,7 +8113,7 @@ void HistoryWidget::drawField(Painter &p) {
|
||||||
backh += st::replyHeight;
|
backh += st::replyHeight;
|
||||||
}
|
}
|
||||||
bool drawPreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed;
|
bool drawPreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed;
|
||||||
p.fillRect(0, backy, width(), backh, st::taMsgField.bgColor->b);
|
p.fillRect(0, backy, width(), backh, st::taMsgField.bgColor);
|
||||||
if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) {
|
if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) {
|
||||||
int32 replyLeft = st::replySkip;
|
int32 replyLeft = st::replySkip;
|
||||||
p.drawSprite(QPoint(st::replyIconPos.x(), backy + st::replyIconPos.y()), _editMsgId ? st::editIcon : st::replyIcon);
|
p.drawSprite(QPoint(st::replyIconPos.x(), backy + st::replyIconPos.y()), _editMsgId ? st::editIcon : st::replyIcon);
|
||||||
|
@ -8126,8 +8129,7 @@ void HistoryWidget::drawField(Painter &p) {
|
||||||
}
|
}
|
||||||
p.setPen(st::replyColor);
|
p.setPen(st::replyColor);
|
||||||
if (_editMsgId) {
|
if (_editMsgId) {
|
||||||
p.setFont(st::msgServiceNameFont);
|
paintEditHeader(p, rect, replyLeft, backy);
|
||||||
p.drawText(replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->ascent, lang(lng_edit_message));
|
|
||||||
} else {
|
} else {
|
||||||
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel.width() - st::msgReplyPadding.right());
|
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel.width() - st::msgReplyPadding.right());
|
||||||
}
|
}
|
||||||
|
@ -8182,6 +8184,56 @@ void HistoryWidget::drawField(Painter &p) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr int DisplayEditTimeWarningMs = 900 * 1000;
|
||||||
|
constexpr int FullDayInMs = 86400 * 1000;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int top) const {
|
||||||
|
if (!rect.intersects(QRect(left, top, width() - left, st::normalFont->height))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.setFont(st::msgServiceNameFont);
|
||||||
|
p.drawText(left, top + st::msgReplyPadding.top() + st::msgServiceNameFont->ascent, lang(lng_edit_message));
|
||||||
|
|
||||||
|
if (!_replyEditMsg) return;
|
||||||
|
|
||||||
|
QString editTimeLeftText;
|
||||||
|
int updateIn = -1;
|
||||||
|
auto tmp = ::date(unixtime());
|
||||||
|
auto timeSinceMessage = _replyEditMsg->date.msecsTo(QDateTime::currentDateTime());
|
||||||
|
auto editTimeLeft = (Global::EditTimeLimit() * 1000LL) - timeSinceMessage;
|
||||||
|
if (editTimeLeft < 2) {
|
||||||
|
editTimeLeftText = qsl("0:00");
|
||||||
|
} else if (editTimeLeft > DisplayEditTimeWarningMs) {
|
||||||
|
updateIn = static_cast<int>(qMin(editTimeLeft - DisplayEditTimeWarningMs, qint64(FullDayInMs)));
|
||||||
|
} else {
|
||||||
|
updateIn = (editTimeLeft % 1000);
|
||||||
|
if (!updateIn) {
|
||||||
|
updateIn = 1000;
|
||||||
|
}
|
||||||
|
++updateIn;
|
||||||
|
|
||||||
|
editTimeLeft = (editTimeLeft - 1) / 1000; // seconds
|
||||||
|
editTimeLeftText = qsl("%1:%2").arg(editTimeLeft / 60).arg(editTimeLeft % 60, 2, 10, QChar('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restart timer only if we are sure that we've painted the whole timer.
|
||||||
|
if (rect.contains(QRect(left, top, width() - left, st::normalFont->height)) && updateIn > 0) {
|
||||||
|
_updateEditTimeLeftDisplay.start(updateIn);
|
||||||
|
LOG(("Time since message: %1ms, update in %2ms: %3").arg(timeSinceMessage).arg(updateIn).arg(editTimeLeftText));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!editTimeLeftText.isEmpty()) {
|
||||||
|
p.setFont(st::normalFont);
|
||||||
|
p.setPen(st::msgInDateFg);
|
||||||
|
p.drawText(left + st::msgServiceNameFont->width(lang(lng_edit_message)) + st::normalFont->spacew, top + st::msgReplyPadding.top() + st::msgServiceNameFont->ascent, editTimeLeftText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::drawRecordButton(Painter &p) {
|
void HistoryWidget::drawRecordButton(Painter &p) {
|
||||||
if (a_recordDown.current() < 1) {
|
if (a_recordDown.current() < 1) {
|
||||||
p.setOpacity(st::btnAttachEmoji.opacity * (1 - a_recordOver.current()) + st::btnAttachEmoji.overOpacity * a_recordOver.current());
|
p.setOpacity(st::btnAttachEmoji.opacity * (1 - a_recordOver.current()) + st::btnAttachEmoji.overOpacity * a_recordOver.current());
|
||||||
|
@ -8308,7 +8360,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
if (_list) {
|
if (_list) {
|
||||||
if (!_field.isHidden() || _recording) {
|
if (!_field.isHidden() || _recording) {
|
||||||
drawField(p);
|
drawField(p, r);
|
||||||
if (_send.isHidden()) {
|
if (_send.isHidden()) {
|
||||||
drawRecordButton(p);
|
drawRecordButton(p);
|
||||||
if (_recording) drawRecording(p);
|
if (_recording) drawRecording(p);
|
||||||
|
|
|
@ -791,7 +791,6 @@ public slots:
|
||||||
void onDraftSave(bool delayed = false);
|
void onDraftSave(bool delayed = false);
|
||||||
|
|
||||||
void updateStickers();
|
void updateStickers();
|
||||||
void updateField();
|
|
||||||
|
|
||||||
void onRecordError();
|
void onRecordError();
|
||||||
void onRecordDone(QByteArray result, VoiceWaveform waveform, qint32 samples);
|
void onRecordDone(QByteArray result, VoiceWaveform waveform, qint32 samples);
|
||||||
|
@ -809,6 +808,8 @@ private slots:
|
||||||
void onMentionInsert(UserData *user);
|
void onMentionInsert(UserData *user);
|
||||||
void onInlineBotCancel();
|
void onInlineBotCancel();
|
||||||
|
|
||||||
|
void updateField();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Updates position of controls around the message field,
|
// Updates position of controls around the message field,
|
||||||
|
@ -834,6 +835,7 @@ private:
|
||||||
|
|
||||||
HistoryItem *_replyEditMsg = nullptr;
|
HistoryItem *_replyEditMsg = nullptr;
|
||||||
Text _replyEditMsgText;
|
Text _replyEditMsgText;
|
||||||
|
mutable SingleTimer _updateEditTimeLeftDisplay;
|
||||||
|
|
||||||
IconedButton _fieldBarCancel;
|
IconedButton _fieldBarCancel;
|
||||||
void updateReplyEditTexts(bool force = false);
|
void updateReplyEditTexts(bool force = false);
|
||||||
|
@ -861,7 +863,8 @@ private:
|
||||||
void sendExistingDocument(DocumentData *doc, const QString &caption);
|
void sendExistingDocument(DocumentData *doc, const QString &caption);
|
||||||
void sendExistingPhoto(PhotoData *photo, const QString &caption);
|
void sendExistingPhoto(PhotoData *photo, const QString &caption);
|
||||||
|
|
||||||
void drawField(Painter &p);
|
void drawField(Painter &p, const QRect &rect);
|
||||||
|
void paintEditHeader(Painter &p, const QRect &rect, int left, int top) const;
|
||||||
void drawRecordButton(Painter &p);
|
void drawRecordButton(Painter &p);
|
||||||
void drawRecording(Painter &p);
|
void drawRecording(Painter &p);
|
||||||
void drawPinnedBar(Painter &p);
|
void drawPinnedBar(Painter &p);
|
||||||
|
|
Loading…
Add table
Reference in a new issue