mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 15:13:57 +02:00
Open video from ?t= links.
This commit is contained in:
parent
1e77a3df20
commit
2077f51084
14 changed files with 86 additions and 74 deletions
|
@ -317,6 +317,7 @@ PreviewWrap::PreviewWrap(
|
||||||
0, // duration
|
0, // duration
|
||||||
QString(), // author
|
QString(), // author
|
||||||
false, // hasLargeMedia
|
false, // hasLargeMedia
|
||||||
|
false, // photoIsVideoCover
|
||||||
0)) // pendingTill
|
0)) // pendingTill
|
||||||
, _theme(theme)
|
, _theme(theme)
|
||||||
, _style(style)
|
, _style(style)
|
||||||
|
|
|
@ -598,6 +598,8 @@ bool ResolveUsernameOrPhone(
|
||||||
const auto threadParam = params.value(u"thread"_q);
|
const auto threadParam = params.value(u"thread"_q);
|
||||||
const auto threadId = topicId ? topicId : threadParam.toInt();
|
const auto threadId = topicId ? topicId : threadParam.toInt();
|
||||||
const auto gameParam = params.value(u"game"_q);
|
const auto gameParam = params.value(u"game"_q);
|
||||||
|
const auto videot = params.value(u"t"_q);
|
||||||
|
|
||||||
if (!gameParam.isEmpty() && validDomain(gameParam)) {
|
if (!gameParam.isEmpty() && validDomain(gameParam)) {
|
||||||
startToken = gameParam;
|
startToken = gameParam;
|
||||||
resolveType = ResolveType::ShareGame;
|
resolveType = ResolveType::ShareGame;
|
||||||
|
@ -614,6 +616,9 @@ bool ResolveUsernameOrPhone(
|
||||||
.phone = phone,
|
.phone = phone,
|
||||||
.messageId = post,
|
.messageId = post,
|
||||||
.storyId = storyId,
|
.storyId = storyId,
|
||||||
|
.videoTimestamp = (!videot.isEmpty()
|
||||||
|
? ParseVideoTimestamp(videot)
|
||||||
|
: std::optional<TimeId>()),
|
||||||
.text = params.value(u"text"_q),
|
.text = params.value(u"text"_q),
|
||||||
.repliesInfo = commentId
|
.repliesInfo = commentId
|
||||||
? Window::RepliesByLinkInfo{
|
? Window::RepliesByLinkInfo{
|
||||||
|
@ -1747,4 +1752,14 @@ void ResolveAndShowUniqueGift(
|
||||||
ResolveAndShowUniqueGift(std::move(show), slug, {});
|
ResolveAndShowUniqueGift(std::move(show), slug, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimeId ParseVideoTimestamp(QStringView value) {
|
||||||
|
const auto kExp = u"^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$"_q;
|
||||||
|
const auto m = QRegularExpression(kExp).match(value);
|
||||||
|
return m.hasMatch()
|
||||||
|
? (m.capturedView(1).toInt() * 3600
|
||||||
|
+ m.capturedView(2).toInt() * 60
|
||||||
|
+ m.capturedView(3).toInt())
|
||||||
|
: value.toInt();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
|
@ -50,4 +50,6 @@ void ResolveAndShowUniqueGift(
|
||||||
std::shared_ptr<ChatHelpers::Show> show,
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
const QString &slug);
|
const QString &slug);
|
||||||
|
|
||||||
|
[[nodiscard]] TimeId ParseVideoTimestamp(QStringView value);
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
|
@ -3469,6 +3469,7 @@ not_null<WebPageData*> Session::processWebpage(
|
||||||
0,
|
0,
|
||||||
QString(),
|
QString(),
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
data.vdate().v
|
data.vdate().v
|
||||||
? data.vdate().v
|
? data.vdate().v
|
||||||
: (base::unixtime::now() + kDefaultPendingTimeout));
|
: (base::unixtime::now() + kDefaultPendingTimeout));
|
||||||
|
@ -3496,6 +3497,7 @@ not_null<WebPageData*> Session::webpage(
|
||||||
0,
|
0,
|
||||||
QString(),
|
QString(),
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
TimeId(0));
|
TimeId(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3516,6 +3518,7 @@ not_null<WebPageData*> Session::webpage(
|
||||||
int duration,
|
int duration,
|
||||||
const QString &author,
|
const QString &author,
|
||||||
bool hasLargeMedia,
|
bool hasLargeMedia,
|
||||||
|
bool photoIsVideoCover,
|
||||||
TimeId pendingTill) {
|
TimeId pendingTill) {
|
||||||
const auto result = webpage(id);
|
const auto result = webpage(id);
|
||||||
webpageApplyFields(
|
webpageApplyFields(
|
||||||
|
@ -3536,6 +3539,7 @@ not_null<WebPageData*> Session::webpage(
|
||||||
duration,
|
duration,
|
||||||
author,
|
author,
|
||||||
hasLargeMedia,
|
hasLargeMedia,
|
||||||
|
photoIsVideoCover,
|
||||||
pendingTill);
|
pendingTill);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3723,6 +3727,7 @@ void Session::webpageApplyFields(
|
||||||
data.vduration().value_or_empty(),
|
data.vduration().value_or_empty(),
|
||||||
qs(data.vauthor().value_or_empty()),
|
qs(data.vauthor().value_or_empty()),
|
||||||
data.is_has_large_media(),
|
data.is_has_large_media(),
|
||||||
|
false, // photo_is_video_cover
|
||||||
pendingTill);
|
pendingTill);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3744,6 +3749,7 @@ void Session::webpageApplyFields(
|
||||||
int duration,
|
int duration,
|
||||||
const QString &author,
|
const QString &author,
|
||||||
bool hasLargeMedia,
|
bool hasLargeMedia,
|
||||||
|
bool photoIsVideoCover,
|
||||||
TimeId pendingTill) {
|
TimeId pendingTill) {
|
||||||
const auto requestPending = (!page->pendingTill && pendingTill > 0);
|
const auto requestPending = (!page->pendingTill && pendingTill > 0);
|
||||||
const auto changed = page->applyChanges(
|
const auto changed = page->applyChanges(
|
||||||
|
@ -3763,6 +3769,7 @@ void Session::webpageApplyFields(
|
||||||
duration,
|
duration,
|
||||||
author,
|
author,
|
||||||
hasLargeMedia,
|
hasLargeMedia,
|
||||||
|
photoIsVideoCover,
|
||||||
pendingTill);
|
pendingTill);
|
||||||
if (requestPending) {
|
if (requestPending) {
|
||||||
_session->api().requestWebPageDelayed(page);
|
_session->api().requestWebPageDelayed(page);
|
||||||
|
|
|
@ -631,6 +631,7 @@ public:
|
||||||
int duration,
|
int duration,
|
||||||
const QString &author,
|
const QString &author,
|
||||||
bool hasLargeMedia,
|
bool hasLargeMedia,
|
||||||
|
bool photoIsVideoCover,
|
||||||
TimeId pendingTill);
|
TimeId pendingTill);
|
||||||
|
|
||||||
[[nodiscard]] not_null<GameData*> game(GameId id);
|
[[nodiscard]] not_null<GameData*> game(GameId id);
|
||||||
|
@ -916,6 +917,7 @@ private:
|
||||||
int duration,
|
int duration,
|
||||||
const QString &author,
|
const QString &author,
|
||||||
bool hasLargeMedia,
|
bool hasLargeMedia,
|
||||||
|
bool photoIsVideoCover,
|
||||||
TimeId pendingTill);
|
TimeId pendingTill);
|
||||||
|
|
||||||
void gameApplyFields(
|
void gameApplyFields(
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
#include "core/local_url_handlers.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "iv/iv_data.h"
|
#include "iv/iv_data.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
|
@ -228,6 +229,7 @@ bool WebPageData::applyChanges(
|
||||||
int newDuration,
|
int newDuration,
|
||||||
const QString &newAuthor,
|
const QString &newAuthor,
|
||||||
bool newHasLargeMedia,
|
bool newHasLargeMedia,
|
||||||
|
bool newPhotoIsVideoCover,
|
||||||
int newPendingTill) {
|
int newPendingTill) {
|
||||||
if (newPendingTill != 0
|
if (newPendingTill != 0
|
||||||
&& (!url.isEmpty() || failed)
|
&& (!url.isEmpty() || failed)
|
||||||
|
@ -265,6 +267,9 @@ bool WebPageData::applyChanges(
|
||||||
|| (hasSiteName + hasTitle + hasDescription < 2)) {
|
|| (hasSiteName + hasTitle + hasDescription < 2)) {
|
||||||
newHasLargeMedia = false;
|
newHasLargeMedia = false;
|
||||||
}
|
}
|
||||||
|
if (!newDocument || !newDocument->isVideoFile() || !newPhoto) {
|
||||||
|
newPhotoIsVideoCover = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == newType
|
if (type == newType
|
||||||
&& url == resultUrl
|
&& url == resultUrl
|
||||||
|
@ -283,6 +288,7 @@ bool WebPageData::applyChanges(
|
||||||
&& duration == newDuration
|
&& duration == newDuration
|
||||||
&& author == resultAuthor
|
&& author == resultAuthor
|
||||||
&& hasLargeMedia == (newHasLargeMedia ? 1 : 0)
|
&& hasLargeMedia == (newHasLargeMedia ? 1 : 0)
|
||||||
|
&& photoIsVideoCover == (newPhotoIsVideoCover ? 1 : 0)
|
||||||
&& pendingTill == newPendingTill) {
|
&& pendingTill == newPendingTill) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -291,6 +297,7 @@ bool WebPageData::applyChanges(
|
||||||
}
|
}
|
||||||
type = newType;
|
type = newType;
|
||||||
hasLargeMedia = newHasLargeMedia ? 1 : 0;
|
hasLargeMedia = newHasLargeMedia ? 1 : 0;
|
||||||
|
photoIsVideoCover = newPhotoIsVideoCover ? 1 : 0;
|
||||||
url = resultUrl;
|
url = resultUrl;
|
||||||
displayUrl = resultDisplayUrl;
|
displayUrl = resultDisplayUrl;
|
||||||
siteName = resultSiteName;
|
siteName = resultSiteName;
|
||||||
|
@ -383,14 +390,7 @@ TimeId WebPageData::extractVideoTimestamp() const {
|
||||||
const auto parts = params.split('&');
|
const auto parts = params.split('&');
|
||||||
for (const auto &part : parts) {
|
for (const auto &part : parts) {
|
||||||
if (part.startsWith(u"t="_q)) {
|
if (part.startsWith(u"t="_q)) {
|
||||||
const auto value = part.mid(2);
|
return Core::ParseVideoTimestamp(part.mid(2));
|
||||||
const auto kExp = u"^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$"_q;
|
|
||||||
const auto m = QRegularExpression(kExp).match(value);
|
|
||||||
return m.hasMatch()
|
|
||||||
? (m.capturedView(1).toInt() * 3600
|
|
||||||
+ m.capturedView(2).toInt() * 60
|
|
||||||
+ m.capturedView(3).toInt())
|
|
||||||
: value.toInt();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -106,6 +106,7 @@ struct WebPageData {
|
||||||
int newDuration,
|
int newDuration,
|
||||||
const QString &newAuthor,
|
const QString &newAuthor,
|
||||||
bool newHasLargeMedia,
|
bool newHasLargeMedia,
|
||||||
|
bool newPhotoIsVideoCover,
|
||||||
int newPendingTill);
|
int newPendingTill);
|
||||||
|
|
||||||
static void ApplyChanges(
|
static void ApplyChanges(
|
||||||
|
@ -135,7 +136,8 @@ struct WebPageData {
|
||||||
std::shared_ptr<Data::UniqueGift> uniqueGift;
|
std::shared_ptr<Data::UniqueGift> uniqueGift;
|
||||||
int duration = 0;
|
int duration = 0;
|
||||||
TimeId pendingTill = 0;
|
TimeId pendingTill = 0;
|
||||||
uint32 version : 30 = 0;
|
uint32 version : 29 = 0;
|
||||||
|
uint32 photoIsVideoCover : 1 = 0;
|
||||||
uint32 hasLargeMedia : 1 = 0;
|
uint32 hasLargeMedia : 1 = 0;
|
||||||
uint32 failed : 1 = 0;
|
uint32 failed : 1 = 0;
|
||||||
|
|
||||||
|
|
|
@ -726,6 +726,7 @@ HistoryItem::HistoryItem(
|
||||||
0,
|
0,
|
||||||
QString(),
|
QString(),
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
0);
|
0);
|
||||||
auto webpageMedia = std::make_unique<Data::MediaWebPage>(
|
auto webpageMedia = std::make_unique<Data::MediaWebPage>(
|
||||||
this,
|
this,
|
||||||
|
|
|
@ -2207,15 +2207,12 @@ bool HistoryWidget::insideJumpToEndInsteadOfToUnread() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::showHistory(
|
void HistoryWidget::showHistory(
|
||||||
const PeerId &peerId,
|
PeerId peerId,
|
||||||
MsgId showAtMsgId,
|
MsgId showAtMsgId,
|
||||||
const TextWithEntities &highlightPart,
|
const Window::SectionShow ¶ms) {
|
||||||
int highlightPartOffsetHint) {
|
|
||||||
|
|
||||||
_pinnedClickedId = FullMsgId();
|
_pinnedClickedId = FullMsgId();
|
||||||
_minPinnedId = std::nullopt;
|
_minPinnedId = std::nullopt;
|
||||||
_showAtMsgHighlightPart = {};
|
_showAtMsgParams = {};
|
||||||
_showAtMsgHighlightPartOffsetHint = 0;
|
|
||||||
|
|
||||||
const auto wasState = controller()->dialogsEntryStateCurrent();
|
const auto wasState = controller()->dialogsEntryStateCurrent();
|
||||||
const auto startBot = (showAtMsgId == ShowAndStartBotMsgId);
|
const auto startBot = (showAtMsgId == ShowAndStartBotMsgId);
|
||||||
|
@ -2265,16 +2262,10 @@ void HistoryWidget::showHistory(
|
||||||
).arg(_history->inboxReadTillId().bare
|
).arg(_history->inboxReadTillId().bare
|
||||||
).arg(Logs::b(_history->loadedAtBottom())
|
).arg(Logs::b(_history->loadedAtBottom())
|
||||||
).arg(showAtMsgId.bare));
|
).arg(showAtMsgId.bare));
|
||||||
delayedShowAt(
|
delayedShowAt(showAtMsgId, params);
|
||||||
showAtMsgId,
|
|
||||||
highlightPart,
|
|
||||||
highlightPartOffsetHint);
|
|
||||||
} else if (_showAtMsgId != showAtMsgId) {
|
} else if (_showAtMsgId != showAtMsgId) {
|
||||||
clearAllLoadRequests();
|
clearAllLoadRequests();
|
||||||
setMsgId(
|
setMsgId(showAtMsgId, params);
|
||||||
showAtMsgId,
|
|
||||||
highlightPart,
|
|
||||||
highlightPartOffsetHint);
|
|
||||||
firstLoadMessages();
|
firstLoadMessages();
|
||||||
doneShow();
|
doneShow();
|
||||||
}
|
}
|
||||||
|
@ -2294,10 +2285,7 @@ void HistoryWidget::showHistory(
|
||||||
_cornerButtons.skipReplyReturn(skipId);
|
_cornerButtons.skipReplyReturn(skipId);
|
||||||
}
|
}
|
||||||
|
|
||||||
setMsgId(
|
setMsgId(showAtMsgId, params);
|
||||||
showAtMsgId,
|
|
||||||
highlightPart,
|
|
||||||
highlightPartOffsetHint);
|
|
||||||
if (_historyInited) {
|
if (_historyInited) {
|
||||||
DEBUG_LOG(("JumpToEnd(%1, %2, %3): "
|
DEBUG_LOG(("JumpToEnd(%1, %2, %3): "
|
||||||
"Showing instant at %4."
|
"Showing instant at %4."
|
||||||
|
@ -2402,8 +2390,7 @@ void HistoryWidget::showHistory(
|
||||||
clearInlineBot();
|
clearInlineBot();
|
||||||
|
|
||||||
_showAtMsgId = showAtMsgId;
|
_showAtMsgId = showAtMsgId;
|
||||||
_showAtMsgHighlightPart = highlightPart;
|
_showAtMsgParams = params;
|
||||||
_showAtMsgHighlightPartOffsetHint = highlightPartOffsetHint;
|
|
||||||
_historyInited = false;
|
_historyInited = false;
|
||||||
_contactStatus = nullptr;
|
_contactStatus = nullptr;
|
||||||
_businessBotStatus = nullptr;
|
_businessBotStatus = nullptr;
|
||||||
|
@ -3642,10 +3629,7 @@ void HistoryWidget::messagesReceived(
|
||||||
}
|
}
|
||||||
|
|
||||||
_delayedShowAtRequest = 0;
|
_delayedShowAtRequest = 0;
|
||||||
setMsgId(
|
setMsgId(_delayedShowAtMsgId, _delayedShowAtMsgParams);
|
||||||
_delayedShowAtMsgId,
|
|
||||||
_delayedShowAtMsgHighlightPart,
|
|
||||||
_delayedShowAtMsgHighlightPartOffsetHint);
|
|
||||||
historyLoaded();
|
historyLoaded();
|
||||||
}
|
}
|
||||||
if (session().supportMode()) {
|
if (session().supportMode()) {
|
||||||
|
@ -3897,15 +3881,11 @@ void HistoryWidget::loadMessagesDown() {
|
||||||
|
|
||||||
void HistoryWidget::delayedShowAt(
|
void HistoryWidget::delayedShowAt(
|
||||||
MsgId showAtMsgId,
|
MsgId showAtMsgId,
|
||||||
const TextWithEntities &highlightPart,
|
const Window::SectionShow ¶ms) {
|
||||||
int highlightPartOffsetHint) {
|
|
||||||
if (!_history) {
|
if (!_history) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_delayedShowAtMsgHighlightPart != highlightPart) {
|
_delayedShowAtMsgParams = params;
|
||||||
_delayedShowAtMsgHighlightPart = highlightPart;
|
|
||||||
}
|
|
||||||
_delayedShowAtMsgHighlightPartOffsetHint = highlightPartOffsetHint;
|
|
||||||
if (_delayedShowAtRequest && _delayedShowAtMsgId == showAtMsgId) {
|
if (_delayedShowAtRequest && _delayedShowAtMsgId == showAtMsgId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4539,12 +4519,8 @@ PeerData *HistoryWidget::peer() const {
|
||||||
// Sometimes _showAtMsgId is set directly.
|
// Sometimes _showAtMsgId is set directly.
|
||||||
void HistoryWidget::setMsgId(
|
void HistoryWidget::setMsgId(
|
||||||
MsgId showAtMsgId,
|
MsgId showAtMsgId,
|
||||||
const TextWithEntities &highlightPart,
|
const Window::SectionShow ¶ms) {
|
||||||
int highlightPartOffsetHint) {
|
_showAtMsgParams = params;
|
||||||
if (_showAtMsgHighlightPart != highlightPart) {
|
|
||||||
_showAtMsgHighlightPart = highlightPart;
|
|
||||||
}
|
|
||||||
_showAtMsgHighlightPartOffsetHint = highlightPartOffsetHint;
|
|
||||||
if (_showAtMsgId != showAtMsgId) {
|
if (_showAtMsgId != showAtMsgId) {
|
||||||
_showAtMsgId = showAtMsgId;
|
_showAtMsgId = showAtMsgId;
|
||||||
if (_history) {
|
if (_history) {
|
||||||
|
@ -6289,8 +6265,8 @@ int HistoryWidget::countInitialScrollTop() {
|
||||||
|
|
||||||
enqueueMessageHighlight({
|
enqueueMessageHighlight({
|
||||||
item,
|
item,
|
||||||
base::take(_showAtMsgHighlightPart),
|
base::take(_showAtMsgParams.highlightPart),
|
||||||
base::take(_showAtMsgHighlightPartOffsetHint),
|
base::take(_showAtMsgParams.highlightPartOffsetHint),
|
||||||
});
|
});
|
||||||
const auto result = itemTopForHighlight(view);
|
const auto result = itemTopForHighlight(view);
|
||||||
createUnreadBarIfBelowVisibleArea(result);
|
createUnreadBarIfBelowVisibleArea(result);
|
||||||
|
@ -6507,6 +6483,22 @@ void HistoryWidget::updateHistoryGeometry(
|
||||||
}
|
}
|
||||||
const auto toY = std::clamp(newScrollTop, 0, _scroll->scrollTopMax());
|
const auto toY = std::clamp(newScrollTop, 0, _scroll->scrollTopMax());
|
||||||
synteticScrollToY(toY);
|
synteticScrollToY(toY);
|
||||||
|
if (initial && _showAtMsgId) {
|
||||||
|
const auto timestamp = base::take(_showAtMsgParams.videoTimestamp);
|
||||||
|
if (timestamp.has_value()) {
|
||||||
|
const auto item = session().data().message(_peer, _showAtMsgId);
|
||||||
|
const auto media = item ? item->media() : nullptr;
|
||||||
|
const auto document = media ? media->document() : nullptr;
|
||||||
|
if (document && document->isVideoFile()) {
|
||||||
|
controller()->openDocument(
|
||||||
|
document,
|
||||||
|
true,
|
||||||
|
{ item->fullId() },
|
||||||
|
nullptr,
|
||||||
|
timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::revealItemsCallback() {
|
void HistoryWidget::revealItemsCallback() {
|
||||||
|
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "chat_helpers/field_characters_count_manager.h"
|
#include "chat_helpers/field_characters_count_manager.h"
|
||||||
#include "data/data_report.h"
|
#include "data/data_report.h"
|
||||||
#include "window/section_widget.h"
|
#include "window/section_widget.h"
|
||||||
|
#include "window/window_session_controller.h"
|
||||||
#include "ui/widgets/fields/input_field.h"
|
#include "ui/widgets/fields/input_field.h"
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
|
|
||||||
|
@ -86,10 +87,6 @@ namespace Webrtc {
|
||||||
enum class RecordAvailability : uchar;
|
enum class RecordAvailability : uchar;
|
||||||
} // namespace Webrtc
|
} // namespace Webrtc
|
||||||
|
|
||||||
namespace Window {
|
|
||||||
class SessionController;
|
|
||||||
} // namespace Window
|
|
||||||
|
|
||||||
namespace ChatHelpers {
|
namespace ChatHelpers {
|
||||||
class TabbedPanel;
|
class TabbedPanel;
|
||||||
class TabbedSelector;
|
class TabbedSelector;
|
||||||
|
@ -160,10 +157,7 @@ public:
|
||||||
void loadMessages();
|
void loadMessages();
|
||||||
void loadMessagesDown();
|
void loadMessagesDown();
|
||||||
void firstLoadMessages();
|
void firstLoadMessages();
|
||||||
void delayedShowAt(
|
void delayedShowAt(MsgId showAtMsgId, const Window::SectionShow ¶ms);
|
||||||
MsgId showAtMsgId,
|
|
||||||
const TextWithEntities &highlightPart,
|
|
||||||
int highlightPartOffsetHint);
|
|
||||||
|
|
||||||
bool updateReplaceMediaButton();
|
bool updateReplaceMediaButton();
|
||||||
void updateFieldPlaceholder();
|
void updateFieldPlaceholder();
|
||||||
|
@ -176,10 +170,7 @@ public:
|
||||||
|
|
||||||
History *history() const;
|
History *history() const;
|
||||||
PeerData *peer() const;
|
PeerData *peer() const;
|
||||||
void setMsgId(
|
void setMsgId(MsgId showAtMsgId, const Window::SectionShow ¶ms = {});
|
||||||
MsgId showAtMsgId,
|
|
||||||
const TextWithEntities &highlightPart = {},
|
|
||||||
int highlightPartOffsetHint = 0);
|
|
||||||
MsgId msgId() const;
|
MsgId msgId() const;
|
||||||
|
|
||||||
bool hasTopBarShadow() const {
|
bool hasTopBarShadow() const {
|
||||||
|
@ -244,10 +235,9 @@ public:
|
||||||
bool applyDraft(
|
bool applyDraft(
|
||||||
FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
|
FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
|
||||||
void showHistory(
|
void showHistory(
|
||||||
const PeerId &peer,
|
PeerId peerId,
|
||||||
MsgId showAtMsgId,
|
MsgId showAtMsgId,
|
||||||
const TextWithEntities &highlightPart = {},
|
const Window::SectionShow ¶ms = {});
|
||||||
int highlightPartOffsetHint = 0);
|
|
||||||
void setChooseReportMessagesDetails(
|
void setChooseReportMessagesDetails(
|
||||||
Data::ReportInput reportInput,
|
Data::ReportInput reportInput,
|
||||||
Fn<void(std::vector<MsgId>)> callback);
|
Fn<void(std::vector<MsgId>)> callback);
|
||||||
|
@ -728,8 +718,7 @@ private:
|
||||||
bool _canSendTexts = false;
|
bool _canSendTexts = false;
|
||||||
MsgId _showAtMsgId = ShowAtUnreadMsgId;
|
MsgId _showAtMsgId = ShowAtUnreadMsgId;
|
||||||
base::flat_set<MsgId> _topicsRequested;
|
base::flat_set<MsgId> _topicsRequested;
|
||||||
TextWithEntities _showAtMsgHighlightPart;
|
Window::SectionShow _showAtMsgParams;
|
||||||
int _showAtMsgHighlightPartOffsetHint = 0;
|
|
||||||
bool _showAndMaybeSendStart = false;
|
bool _showAndMaybeSendStart = false;
|
||||||
|
|
||||||
int _firstLoadRequest = 0; // Not real mtpRequestId.
|
int _firstLoadRequest = 0; // Not real mtpRequestId.
|
||||||
|
@ -737,8 +726,7 @@ private:
|
||||||
int _preloadDownRequest = 0; // Not real mtpRequestId.
|
int _preloadDownRequest = 0; // Not real mtpRequestId.
|
||||||
|
|
||||||
MsgId _delayedShowAtMsgId = -1;
|
MsgId _delayedShowAtMsgId = -1;
|
||||||
TextWithEntities _delayedShowAtMsgHighlightPart;
|
Window::SectionShow _delayedShowAtMsgParams;
|
||||||
int _delayedShowAtMsgHighlightPartOffsetHint = 0;
|
|
||||||
int _delayedShowAtRequest = 0; // Not real mtpRequestId.
|
int _delayedShowAtRequest = 0; // Not real mtpRequestId.
|
||||||
|
|
||||||
History *_supportPreloadHistory = nullptr;
|
History *_supportPreloadHistory = nullptr;
|
||||||
|
|
|
@ -1449,11 +1449,7 @@ void MainWidget::showHistory(
|
||||||
&& way != Way::Forward) {
|
&& way != Way::Forward) {
|
||||||
ClearBotStartToken(_history->peer());
|
ClearBotStartToken(_history->peer());
|
||||||
}
|
}
|
||||||
_history->showHistory(
|
_history->showHistory(peerId, showAtMsgId, params);
|
||||||
peerId,
|
|
||||||
showAtMsgId,
|
|
||||||
params.highlightPart,
|
|
||||||
params.highlightPartOffsetHint);
|
|
||||||
if (alreadyThatPeer && params.reapplyLocalDraft) {
|
if (alreadyThatPeer && params.reapplyLocalDraft) {
|
||||||
_history->applyDraft(HistoryWidget::FieldHistoryAction::NewEntry);
|
_history->applyDraft(HistoryWidget::FieldHistoryAction::NewEntry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -755,6 +755,7 @@ void SessionNavigation::showPeerByLinkResolved(
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const auto draft = info.text;
|
const auto draft = info.text;
|
||||||
|
params.videoTimestamp = info.videoTimestamp;
|
||||||
crl::on_main(this, [=] {
|
crl::on_main(this, [=] {
|
||||||
if (peer->isUser() && !draft.isEmpty()) {
|
if (peer->isUser() && !draft.isEmpty()) {
|
||||||
Data::SetChatLinkDraft(peer, { draft });
|
Data::SetChatLinkDraft(peer, { draft });
|
||||||
|
@ -2780,19 +2781,21 @@ void SessionController::openDocument(
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
bool showInMediaView,
|
bool showInMediaView,
|
||||||
MessageContext message,
|
MessageContext message,
|
||||||
const Data::StoriesContext *stories) {
|
const Data::StoriesContext *stories,
|
||||||
|
std::optional<TimeId> videoTimestampOverride) {
|
||||||
const auto item = session().data().message(message.id);
|
const auto item = session().data().message(message.id);
|
||||||
if (openSharedStory(item) || openFakeItemStory(message.id, stories)) {
|
if (openSharedStory(item) || openFakeItemStory(message.id, stories)) {
|
||||||
return;
|
return;
|
||||||
} else if (showInMediaView) {
|
} else if (showInMediaView) {
|
||||||
using namespace Media::View;
|
using namespace Media::View;
|
||||||
|
const auto timestamp = item ? ExtractVideoTimestamp(item) : 0;
|
||||||
_window->openInMediaView(OpenRequest(
|
_window->openInMediaView(OpenRequest(
|
||||||
this,
|
this,
|
||||||
document,
|
document,
|
||||||
item,
|
item,
|
||||||
message.topicRootId,
|
message.topicRootId,
|
||||||
false,
|
false,
|
||||||
(item ? ExtractVideoTimestamp(item) : 0) * crl::time(1000)));
|
videoTimestampOverride.value_or(timestamp) * crl::time(1000)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Data::ResolveDocument(this, document, item, message.topicRootId);
|
Data::ResolveDocument(this, document, item, message.topicRootId);
|
||||||
|
|
|
@ -158,6 +158,7 @@ struct SectionShow {
|
||||||
|
|
||||||
TextWithEntities highlightPart;
|
TextWithEntities highlightPart;
|
||||||
int highlightPartOffsetHint = 0;
|
int highlightPartOffsetHint = 0;
|
||||||
|
std::optional<TimeId> videoTimestamp;
|
||||||
Way way = Way::Forward;
|
Way way = Way::Forward;
|
||||||
anim::type animated = anim::type::normal;
|
anim::type animated = anim::type::normal;
|
||||||
anim::activation activation = anim::activation::normal;
|
anim::activation activation = anim::activation::normal;
|
||||||
|
@ -505,7 +506,8 @@ public:
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
bool showInMediaView,
|
bool showInMediaView,
|
||||||
MessageContext message,
|
MessageContext message,
|
||||||
const Data::StoriesContext *stories = nullptr);
|
const Data::StoriesContext *stories = nullptr,
|
||||||
|
std::optional<TimeId> videoTimestampOverride = {});
|
||||||
bool openSharedStory(HistoryItem *item);
|
bool openSharedStory(HistoryItem *item);
|
||||||
bool openFakeItemStory(
|
bool openFakeItemStory(
|
||||||
FullMsgId fakeItemId,
|
FullMsgId fakeItemId,
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct PeerByLinkInfo {
|
||||||
QString chatLinkSlug;
|
QString chatLinkSlug;
|
||||||
MsgId messageId = ShowAtUnreadMsgId;
|
MsgId messageId = ShowAtUnreadMsgId;
|
||||||
StoryId storyId = 0;
|
StoryId storyId = 0;
|
||||||
|
std::optional<TimeId> videoTimestamp;
|
||||||
QString text;
|
QString text;
|
||||||
RepliesByLinkInfo repliesInfo;
|
RepliesByLinkInfo repliesInfo;
|
||||||
ResolveType resolveType = ResolveType::Default;
|
ResolveType resolveType = ResolveType::Default;
|
||||||
|
|
Loading…
Add table
Reference in a new issue