Add IV footer.

This commit is contained in:
John Preston 2024-04-26 19:20:43 +04:00
parent a272807a99
commit 7addcf2d25
8 changed files with 93 additions and 20 deletions

View file

@ -134,9 +134,32 @@ html.custom_scroll ::-webkit-scrollbar-thumb:hover {
.page-slide {
position: relative;
width: 100%;
min-height: 100%;
margin-left: 0%;
transition: margin 240ms ease-in-out;
}
.page-footer {
height: 32px;
margin-top: -32px;
background: var(--td-window-bg-over);
}
.page-footer .content {
padding: 3px 18px;
font-size: 15px;
color: var(--td-window-sub-text-fg);
text-align: center;
}
.page-footer .wrong {
position: relative;
padding: 5px;
margin: -5px;
color: var(--td-window-sub-text-fg);
text-decoration: none;
cursor: pointer;
}
.page-footer .wrong:hover {
text-decoration: underline;
}
.hidden-left,
.hidden-right {
pointer-events: none;
@ -148,7 +171,7 @@ html.custom_scroll ::-webkit-scrollbar-thumb:hover {
margin-left: 100%;
}
article {
padding-bottom: 12px;
padding-bottom: 40px;
overflow-y: hidden;
overflow-x: auto;
white-space: pre-wrap;
@ -893,6 +916,9 @@ section.related a.related-link:after {
right: 0;
bottom: 0;
}
section.related a.related-link:last-child:after {
border-bottom: 0px;
}
section.related .related-link-url {
display: block;
font-size: 15px;

View file

@ -26,7 +26,7 @@ var IV = {
}
target = target.parentNode;
}
if (!target || !target.hasAttribute('href')) {
if (!target || (context === '' && !target.hasAttribute('href'))) {
return;
}
var base = document.createElement('A');
@ -413,9 +413,12 @@ var IV = {
var article = function (el) {
return el.getElementsByTagName('article')[0];
};
var from = article(IV.findPageScroll());
var to = article(IV.makeScrolledContent(data.html));
morphdom(from, to, {
var footer = function (el) {
return el.getElementsByClassName('page-footer')[0];
};
var from = IV.findPageScroll();
var to = IV.makeScrolledContent(data.html);
morphdom(article(from), article(to), {
onBeforeElUpdated: function (fromEl, toEl) {
if (fromEl.classList.contains('video')
&& toEl.classList.contains('video')
@ -439,6 +442,7 @@ var IV = {
return !fromEl.isEqualNode(toEl);
}
});
morphdom(footer(from), footer(to));
IV.initMedia();
eval(data.js);
},
@ -477,9 +481,7 @@ var IV = {
var result = document.createElement('div');
result.className = 'page-scroll';
result.tabIndex = '-1';
result.innerHTML = '<div class="page-slide"><article>'
+ html
+ '</article></div>';
result.innerHTML = html.trim();
result.onscroll = IV.frameScrolled;
return result;
},

View file

@ -5111,6 +5111,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_iv_share" = "Share";
"lng_iv_join_channel" = "Join";
"lng_iv_window_title" = "Instant View";
"lng_iv_wrong_layout" = "Wrong layout?";
"lng_limit_download_title" = "Download speed limited";
"lng_limit_download_subscribe" = "Subscribe to {link} and increase download speed {increase}.";

View file

@ -155,10 +155,6 @@ namespace {
+ "IV.init();"
+ page.script;
const auto contentAttributes = page.rtl
? " dir=\"rtl\" class=\"rtl\""_q
: QByteArray();
return R"(<!DOCTYPE html>
<html)"_q
+ classAttribute
@ -179,9 +175,7 @@ namespace {
<path d="M14.9972363,18 L9.13865768,12.1414214 C9.06055283,12.0633165 9.06055283,11.9366835 9.13865768,11.8585786 L14.9972363,6 L14.9972363,6" transform="translate(11.997236, 12.000000) scale(-1, -1) rotate(-90.000000) translate(-11.997236, -12.000000) "></path>
</svg>
</button>
<div class="page-scroll" tabindex="-1"><div class="page-slide">
<article)"_q + contentAttributes + ">"_q + page.content + R"(</article>
</div></div>
<div class="page-scroll" tabindex="-1">)"_q + page.content.trimmed() + R"(</div>
<script>)"_q + js + R"(</script>
</body>
</html>
@ -646,7 +640,12 @@ void Controller::processLink(const QString &url, const QString &context) {
const auto joinPrefix = u"join_link"_q;
const auto webpagePrefix = u"webpage"_q;
const auto viewerPrefix = u"viewer"_q;
if (context.startsWith(channelPrefix)) {
if (context == u"report-iv") {
_events.fire({
.type = Event::Type::Report,
.context = QString::number(compuseCurrentPageId()),
});
} else if (context.startsWith(channelPrefix)) {
_events.fire({
.type = Event::Type::OpenChannel,
.context = context.mid(channelPrefix.size()),
@ -701,6 +700,13 @@ QString Controller::composeCurrentUrl() const {
+ (_hash.isEmpty() ? u""_q : ('#' + _hash));
}
uint64 Controller::compuseCurrentPageId() const {
const auto index = _index.current();
Assert(index >= 0 && index < _pages.size());
return _pages[index].pageId;
}
void Controller::showMenu() {
const auto index = _index.current();
if (_menu || index < 0 || index > _pages.size()) {

View file

@ -63,6 +63,7 @@ public:
OpenLink,
OpenLinkExternal,
OpenMedia,
Report,
};
Type type = Type::Close;
QString url;
@ -116,6 +117,7 @@ private:
void quit();
[[nodiscard]] QString composeCurrentUrl() const;
[[nodiscard]] uint64 compuseCurrentPageId() const;
void showShareMenu();
void destroyShareMenu();

View file

@ -15,6 +15,7 @@ struct Options {
};
struct Prepared {
uint64 pageId = 0;
QString name;
QByteArray content;
QByteArray script;

View file

@ -742,9 +742,7 @@ void Instance::show(
not_null<Data*> data,
QString hash) {
const auto guard = gsl::finally([&] {
if (data->partial()) {
requestFull(session, data->id());
}
requestFull(session, data->id());
});
if (_shown && _shownSession == session) {
_shown->moveTo(data, hash);
@ -834,6 +832,17 @@ void Instance::show(
UrlClickHandler::Open(event.url);
}).send();
break;
case Type::Report:
if (const auto controller = _shownSession->tryResolveWindow()) {
controller->window().activate();
controller->showPeerByLink(Window::PeerByLinkInfo{
.usernameOrId = "previews",
.resolveType = Window::ResolveType::BotStart,
.startToken = ("webpage"
+ QString::number(event.context.toULongLong())),
});
}
break;
}
}, _shown->lifetime());

View file

@ -142,6 +142,8 @@ private:
[[nodiscard]] QByteArray block(
const MTPDpageListOrderedItemBlocks &data);
[[nodiscard]] QByteArray wrap(const QByteArray &content, int views);
[[nodiscard]] QByteArray tag(
const QByteArray &name,
const QByteArray &body = {});
@ -223,9 +225,13 @@ Parser::Parser(const Source &source, const Options &options)
: /*_options(options)
, */_fileOriginPostfix('/' + Number(source.pageId)) {
process(source);
_result.pageId = source.pageId;
_result.name = source.name;
_result.rtl = source.page.data().is_rtl();
_result.content = list(source.page.data().vblocks());
const auto views = source.page.data().vviews().value_or_empty();
const auto content = list(source.page.data().vblocks());
_result.content = wrap(content, views);
}
Prepared Parser::result() {
@ -925,6 +931,26 @@ QByteArray Parser::utf(const tl::conditional<MTPstring> &text) {
return text ? utf(*text) : QByteArray();
}
QByteArray Parser::wrap(const QByteArray &content, int views) {
const auto sep = " \xE2\x80\xA2 ";
const auto viewsText = views
? (tr::lng_stories_views(tr::now, lt_count_decimal, views) + sep)
: QString();
return R"(
<div class="page-slide">
<article>)"_q + content + R"(</article>
</div>
<div class="page-footer">
<div class="content">
)"_q
+ viewsText.toUtf8()
+ R"(<a class="wrong" data-context="report-iv">)"_q
+ tr::lng_iv_wrong_layout(tr::now).toUtf8()
+ R"(</a>
</div>
</div>)"_q;
}
QByteArray Parser::tag(
const QByteArray &name,
const QByteArray &body) {